在项目中踩过的坑

iOS实现自定义键盘

2018-04-25  本文已影响29人  子达如何

使用inputAccessoryView做类似iMessage的输入框,关闭键盘的时候,调用UITextField的resignFirstResponder会有一个warning:rejected resignFirstResponder when being removed from hierarchy。

做法如下:

  1. 自定义一个CustomView,实现canBecomFirstResponder,返回YES;
  2. 实现inputAccessoryView,返回一个带UITextField的View。注意,不要使用UIToolbar了,很难用。以前用UIToolBar挺好的。自从iOS11的UIToolBar改成AutoLayout之后,布局非常难用。
  3. 打开键盘:首先调用自定义CustomView的becomeFirstResponder。系统就会打开键盘,并且访问inputAccessoryView,把inputAccessoryView附加到键盘上。这时候,UITextField是得不到“焦点”的,因为first response 是CustomView而不是UITextField。这就需要做一个延迟调用,让UITextField得到“焦点”。
  4. 在inputAccessoryView中加一个按钮响应关闭键盘。点击按钮关闭键盘,完成输入。
  5. 关闭键盘:调用UITextField的resignFirstResponder和CustomView的resignFirstResponder。
    这里就出现warning了:rejected resignFirstResponder when being removed from hierarchy。

虽然,键盘还是能关闭,但是,总觉得有点不对。
后来在各个方法设置断点调试了一番之后发现问题了。

  1. 当UITextField调用resignFirstResponder之后,系统会再问CustomView是否能成为First Responder(也就是调用canBecomFirstResponder方法,看返回值)
  2. 如果canBecomFirstResponder返回YES,系统又会尝试让CustomView成为First Responder了。

原因是,我们打开键盘的过程,响应链是CustomView--》UITextField。那么,在UITextField结束响应链的时候,自然就回到了CustomView。
问题原因找到了,解决办法就是,做个标记,在关闭键盘的时候canBecomFirstResponder返回NO即可。

上一篇下一篇

猜你喜欢

热点阅读