之前看到同事遇到使用tabelview显示Search Display Controller无法完全显示自动补全的搜索条目的问题,前两天学习的时候遇到storyboard实现的scrollview内部添加控件后,出现无法滚动的问题。在学习scrollview特性的过程中,正好找到了上述问题的解决方案。
查看UIScrollView的SDK文档可以知道,UIScrollerView有个属性:contentInset。
contentInset属性用于改变scrollView的content之外最大的偏移量。它的类型为UIEdgeInsets,由4部分组成:{top, left, bottom, right}。当插入一个inset,其实是改变了content的偏移范围。
可以通过阅读Understanding Scroll Views提升理解。
至于如果处理keyboard显示遮盖问题,在网上能找到利用contentInset属性的解决方法。
原文可见Offset UITableView Content When Keyboard Appears
1、首先注册notifications
在viewDidLoad或者viewWillAppear方法中添加以下的keyboard事件注册。
- (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; }
无论何时,当你注册了这些通知,都要在相应的位置去注销它。所以添加如下代码
- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
2、插入contentInset
下面需要实现注册的keyboardWillShow:方法
- (void)keyboardWillShow:(NSNotification *)notification { CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets; if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) { contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0); } else { contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0); } self.tableView.contentInset = contentInsets; self.tableView.scrollIndicatorInsets = contentInsets; [self.tableView scrollToRowAtIndexPath:self.editingIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; }
但是从坐标信息,我们还无法获取到设备的旋转方向,所以需要检查设备的朝向。
portrait朝向时,我们需要的keyboard的高度就是其高度,但当处于landscape状态时,我们需要获取的keyboard的高度其实是它的宽度。
同样的,这种技巧可以应用于tableview,textview等,这要比直接修改frame好的多。
3、恢复原位置
当keyboard隐藏时,需要充值contentInset。
- (void)keyboardWillHide:(NSNotification *)notification { self.tableView.contentInset = UIEdgeInsetsZero; self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero; }