人生三重境界。第一重境界,看山是山,看水是水;第二重境界,看山不是山,看水不是水;第三重境界,看山还是山,看水还是水。
昨天看《猫妖传》电影解说,让我重新领悟了这句话,当时去电影院并没有理会其中的深奥,觉得特效挺好,大唐盛世。其实不然,当我们学会透过现象看本质的时候,心境会豁然开朗,搞开发也正是如此。
在我离职进行网投这段时间,招聘软件会把一些公司的产品链接显示出来,我感兴趣也会去AppStore下载,特别是充满创新和有魅力的界面。我在实用性>交互>界面进行分析,发现一些App在弱网环境下反复点击提交按钮做网络请求会不停push下级页面,以及输入框在文字编辑超过键盘顶部,会遮挡3行左右文字等没做处理。这些交互的不友好细节,在我以前开发导航类App是从没关注的,所谓看山是山。后来在我做香港护理项目PCW,因为每个院友大量日活数据,特别是多护工分时段提交数据,在数据库查询发现同时间账号有多次记录的时候,就发现问题不容忽视,因为涉及数据的查重,以及医院的检查。下面记录我的解决方法以及心得
我们如果从UI交互入手
首先想到的是避免带有重要post数据按钮重复点击
在实际应用场景中,有几个业务场景需要控制UIButton响应事件的时间间隔。
- 当点击按钮来执行网络请求时,若请求耗时稍长,用户往往会多次点击。这样,就执行了多次请求,造成资源浪费。
- 纯UI交互不带有网络请求,在移动终端设备性能较差时,连续点击按钮会执行多次事件(比如push出来多个viewController)。
- 防止暴力点击。
通过UIButton的enabled属性和userInteractionEnabled属性控制按钮是否可点击。以及用GCD进行延迟交互响应链
此方案在逻辑上比较清晰、易懂,但具体代码书写分散,常常涉及多个地方。
1 | - (void)tapBtn:(UIButton *)btn { |
通过 NSObject
1 | + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument; |
1 |
|
通过打印结果可知,如果连续点击多次,只会响应最后一次点击事件,并且是在设定的时间间隔后执行,这边设置的时间间隔是 2S。
缺点:会出现延时现象,并且需要对大量的UIButton做处理,工作量大,不方便。
通过Runtime交换UIButton的响应事件方法,从而控制响应事件的时间间隔。
- 1 创建一个UIButton的分类,使用runtime增加public属性cs_eventInterval和private属性cs_eventInvalid。
- 在+load方法中使用runtime将UIButton的-sendAction:to:forEvent:方法与自定义的cs_sendAction:to:forEvent:方法进行交换
- 使用cs_eventInterval作为控制cs_eventInvalid的计时因子,用cs_eventInvalid控制UIButton的event事件是否有效果
1 | @interface UIButton (Extension) |
1 |
|
1 |
|
UIButton的sendAction:to:forEvent:方法,实际上交互的是UIControl的sendAction:to:forEvent:方法,所以在使用·UIControl·或其·子类(比如UISlider)·的·sendAction:to:forEvent:·方法时会引起参数缺失的崩溃。
因为在UIButton+Extension.m中的+load方法中交换了UIControl的sendAction:to:forEvent:方法,所以在使用UIControl或其子类(比如UISlider)的sendAction:to:forEvent:方法时会引起参数缺失的崩溃。可以将UIButton+Extension改成UIControl+Extension以避免此问题。
关于键盘弹出的通知细节以及cell的复用动画后面再补充,待续