因为这两个知识点经常一起用到,所以这里就卸载同一篇文章里了。
下面直接进入正题。
## 键盘弹起收回管理
原理需要是利用ios消息传递与消息响应机制。
比方说一个controller里装了一个view,view里装了一个主tableview,这个时候我们可以为view添加一个单击事件:
```
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyBoard)];
tap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:tap];
```
下面是方法实现
```
- (void)closeKeyBoard {
[self.view endEditing:YES]; // 结束编辑 收起键盘
}
```
这个时候普通情况下tableview都会加了许多子控件,当然很有可能会有点击响应事件,这种情况下响应事件会被子控件拦截,并不会走到closeKeyBoard中来。
那么如何来解决这个问题呢。
我们来看看这个属性:
```
self.tableview.userInteractionEnabled = YES; // 使tableview开始正常处理触摸消息
```
这个属性属于UIView 意思是是否处理响应事件。
这么说我们就可以利用这个属性做一些我们想要的功能。
直接上代码:
```
// 注册监听键盘监听方法
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil]; // 监听弹起
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];// 监听收回
```
```
- (void)keyboardWillShow:(NSNotification *)note {
if ([self.commentTextView isFirstResponder]) {
self.tableview.userInteractionEnabled = NO; // 使tableview不处理触摸消息
}
}
// 键盘收回
- (void)keyboardWillHide:(NSNotification *)note {
self.tableview.userInteractionEnabled = YES; // 使tableview开始正常处理触摸消息
}
```
原理非常的简单,就是给view添加一个单击结束编辑状态的事件,然后通过监听键盘收回与弹起改变tableview的userInteractionEnabled即可。
弹起的时候tableview不再响应事件-->单击的时候view响应-->收起键盘
收回的时候tableview正常响应事件-->单击的时候view的子控件响应(如果添加了事件的话,没有添加的话view执行[self.view endEditing:YES]也不影响什么)-->子控件响应响应事件
## 遮挡自适应管理
适用于处理点击uiview(一般用于textfield和textview)之后键盘遮挡的情况
下面直接上代码:
这个简单的赋值写在按钮方法、textfield或者textview的回调中都可以,意思就是把view的相对于屏幕的绝对frame储存在self.selectViewFrame中,具体写在哪里可以按照自己的代码调整。
```
self.selectViewFrame = [view convertRect:view.frame toView:self.view]; // 储存点击的位置 键盘遮挡自适应
```
然后下面就简单了,我们可以通过监听键盘弹起的时候的高度判断是否需要调整位置以让目标控件不让view被键盘遮挡。
这里是键盘的回调方法,具体注册监听上面有说明。
```
- (void)keyboardWillShow:(NSNotification *)note{
//取出键盘最终的frame
CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
//取出键盘弹出需要花费的时间
double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//获取最佳位置距离屏幕上方的距离
if (self.selectViewFrame.origin.y > 0 && (self.selectViewFrame.origin.y + self.selectViewFrame.size.height) > ([UIScreen mainScreen].bounds.size.height - rect.size.height)) {
//键盘的高度 高于textView的高度 需要滚动
[UIView animateWithDuration:duration animations:^{
self.tableview.contentOffset = CGPointMake(0, 20 + self.tableview.contentOffset.y + self.selectViewFrame.origin.y + self.selectViewFrame.size.height - ([UIScreen mainScreen].bounds.size.height - rect.size.height));
}];
}
self.selectViewFrame = CGRectZero;
}
```
原理很简单,如果view相对于屏幕的y + height 大于了键盘相对于屏幕的y值,就做相应的调整即可。
不过下面的两种情况可以做一个优化:
```
// 键盘收回
- (void)keyboardWillHide:(NSNotification *)note {
self.tableview.userInteractionEnabled = YES; // 使tableview开始正常处理触摸消息
// 如果键盘收起时tableview的偏移值超过了范围 则调整
if (self.tableview.contentOffset.y > self.tableview.contentSize.height - self.tableview.bounds.size.height && self.tableview.contentSize.height > self.tableview.bounds.size.height) {
// tableview的内容高度大于tableview高度 并且滑到了底部的情况
[self.tableview setContentOffset:CGPointMake(0, self.tableview.contentSize.height - self.tableview.bounds.size.height) animated:YES];
}
if (self.tableview.contentSize.height < self.tableview.bounds.size.height) {
// tableview的内容高度小于于tableview高度
[self.tableview setContentOffset:CGPointMake(0, 0) animated:YES];
}
}
```
会出现这种情况![](https://img-blog.csdnimg.cn/20210328163913260.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MzkyNTY0OA==,size_16,color_FFFFFF,t_70)
就是偏移值超出contentview的内容。
iOS小萌新记录知识点,如有错误,请联系我[email protected]指正,感谢!