都知道viewWillAppear:方法是在控制器的view将要显示的时候调用的,而viewWillDisappear:方法是在控制器的view将要隐藏的时候调用.
这看上去没什么问题,键盘的显示和隐藏也都能监听到.可是稍微细心下就会发现,苹果在iOS7中增加了导航控制器侧滑返回功能,现在绝大多数App都使用了这项功能(有些App重写了自带的返回键之后忘记开启左滑返回手势了)。那么这项功能会带来什么问题呢?
问题就是:
当触发侧滑返回时会调用系统自带的viewWillDisappear:方法,在该方法中将监听键盘显示和隐藏的通知移除后,要是这时候用户取消了侧滑返回(即回到了原始状态),那么再点击界面上的textField唤出键盘,是不会发送键盘显示和隐藏的通知了,因为通知已被移除。。。
解决方案:
1、将注册监听键盘显示和隐藏的代码放到viewWillAppear:方法中
因为在触发侧滑返回后又取消侧滑,则会调用viewWillAppear:方法。那么如果侧滑返回将通知移除,则在取消侧滑时又会将通知重新添加进去。
2、将移除通知的代码放到dealloc方法中
dealloc方法是在控制器销毁之时调用的。这个时候移除通知而不是在viewWillDisappear:方法中移除可以有效避免上述的问题。既然控制器都销毁了,那么还留着相关的通知干嘛?该移除的移除。
上面给出了两种解决方案,要说哪种最优,那肯定非第二种莫属了。
我在这里可以举个例子。假如我们现在有这么个场景:在控制器的view上有个label,在label上添加一个手势(一般手势都是在创建完label之后添加的),假设我在viewWillDisappear:方法中移除该手势,则此时用户侧滑返回之时又取消侧滑返回,那么原先在label上的手势却再也添加不回来了(这里label一般在viewDidLoad方法中创建),因为viewDidLoad方法不会再次调用。而第二种方法却可以有效避免这种情况,这样就可以避免我这种“手贱”的任意捣鼓了,是不是很完美呢?
总结如下:
1、iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法。
2、在做手势和通知等一系列操作之时尽量在dealloc方法中执行,添加通知尽量在viewDidLoad等一次性方法中执行。
3、在viewWillAppear:、viewWillDisappear:、viewDidAppear:、viewDidDisappear:等类似于这种会多次调用的系统方法中添加代码时,一定要多考虑业务逻辑,以免出现不必要的麻烦。