使用inputAccessoryView做类似iMessage的输入框,关闭键盘的时候,调用UITextField的resignFirstResponder会有一个warning:rejected resignFirstResponder when being removed from hierarchy。
做法如下:
- 自定义一个CustomView,实现canBecomFirstResponder,返回YES;
- 实现inputAccessoryView,返回一个带UITextField的View。注意,不要使用UIToolbar了,很难用。以前用UIToolBar挺好的。自从iOS11的UIToolBar改成AutoLayout之后,布局非常难用。
- 打开键盘:首先调用自定义CustomView的becomeFirstResponder。系统就会打开键盘,并且访问inputAccessoryView,把inputAccessoryView附加到键盘上。这时候,UITextField是得不到“焦点”的,因为first response 是CustomView而不是UITextField。这就需要做一个延迟调用,让UITextField得到“焦点”。
- 在inputAccessoryView中加一个按钮响应关闭键盘。点击按钮关闭键盘,完成输入。
- 关闭键盘:调用UITextField的resignFirstResponder和CustomView的resignFirstResponder。
这里就出现warning了:rejected resignFirstResponder when being removed from hierarchy。
虽然,键盘还是能关闭,但是,总觉得有点不对。
后来在各个方法设置断点调试了一番之后发现问题了。
- 当UITextField调用resignFirstResponder之后,系统会再问CustomView是否能成为First Responder(也就是调用canBecomFirstResponder方法,看返回值)
- 如果canBecomFirstResponder返回YES,系统又会尝试让CustomView成为First Responder了。
原因是,我们打开键盘的过程,响应链是CustomView--》UITextField。那么,在UITextField结束响应链的时候,自然就回到了CustomView。
问题原因找到了,解决办法就是,做个标记,在关闭键盘的时候canBecomFirstResponder返回NO即可。