UIScrollView内容偏移的问题处理(更新到iOS11)
2017-08-16 本文已影响214人
谁的青春不迷茫
问题:
今天想做UITextView的自适应高度,写了个小demo,发现内容偏移了 内容偏移图示可以看到上方有64的偏移,光标是无法到达的。
代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.textView];
[self makeContraints];
}
- (UITextView *)textView
{
if (!_textView) {
_textView = [[UITextView alloc] init];
_textView.backgroundColor = [UIColor grayColor];
_textView.scrollEnabled = NO;
_textView.font = [UIFont systemFontOfSize:20];
}
return _textView;
}
- (void)makeContraints
{
__weak typeof(self) weakSelf = self;
[self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(weakSelf.view);
make.top.mas_equalTo(100);
make.height.greaterThanOrEqualTo(@100);
}];
}
原因:
翻了好久的资料找到了问题。
下面说的UIScrollView包含其子类,UITableView,UICollectionView等
主要是demo中用的导航是透明的,起始坐标是(0, 0),系统会自动偏移UIScrollView让其初始状态从(0,64)显示,但是又能够滑到导航来显示蒙层效果效果如图
-
初始状态因为被偏移了(0,64)所以能够贴导航显示
初始状态
- 导航透明,UIScrollView的起始点在(0,0),所以可以滑动到导航栏显示蒙层效果(
应该是iOS7时苹果觉得这样好看,所以至今默认效果还是这样的
)
蒙层效果
UITextView中的内容就是在一个UIScrollView上,所以系统对最底层对UIScrollView做了偏移。
为什么说是最底层的UIScrollView呢,因为如果在一个UIScrollView中嵌套其他UIScrollView,被嵌套的UIScrollView是不再偏移的,只会偏移最底层那个UIScrollView。
解决方案:
1. 设置ScrollView不自动偏移
[self setAutomaticallyAdjustsScrollViewInsets:NO]
//self.automaticallyAdjustsScrollViewInsets = NO;//同上
iOS11:
在iOS11中UIViewController的automaticallyAdjustsScrollViewInsets
属性被废弃,不再起作用,
取而代之的是UIScrollView中新增的属性contentInsetAdjustmentBehavior
//UITextView继承自UIScrollView,所以也是设置contentInsetAdjustmentBehavior
//效果同iOS11前的self.automaticallyAdjustsScrollViewInsets = NO;
scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
2. 设置导航不透明
self.navigationController.navigationBar.translucent = NO;
3. 边界延伸设置为None
self.edgesForExtendedLayout = UIRectEdgeNone; //默认为UIRectEdgeAll,会向上下左右偏移,偏移到(0,0)
//setf.extendedLayoutIncludesOpaqueBars = NO;//这里系统默认就是NO,如果单设EdgesForExtendedLayout无效可以试试加上这句
4. 手动更改偏移
不建议使用,先不说代码多,由系统设置引起的问题还是由更改设置来解决比较好。这样解决就好像一个人引起的问题,让另一个去解决,不符合代码规范。而且当需要手动设置UIScrollView的contentOffset的时候也会产生冲突。
//循环出UIScrollView手动设置偏移的y为0
for (UIScrollView *view in self.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
CGPoint offset = view.contentOffset;
if (offset.y != 0) {
offset.y = 0;
view.contentOffset = offset;
}
break;
}
}
瞎扯
- 这个问题不是太常见,因为我们现在的导航基本都是不透明的,或者我们的UITextView都在其他UIScrollView上(
需要UITextView的一般都是比较长的视图,比如意见反馈什么的
),所以不会被偏移(前面提到了,只会偏移最底层的UIScrollView
) - 得找到问题的本质。这里就是因为iOS7引入的导航透明,计算坐标为(0,0)引起的系统自动偏移UIScrollView
- 问题解决了当然得写篇博客,给别人参考了。减少别人再次翻找的麻烦,编程需要的就是共享精神,我们在编程时遇到问题还不是大部分靠前人的经验处理吗!!!所以希望大家能贡献自己的力量。予人方便就是予己方便,因为我们也需要从共享中获益。