美文网首页复杂UI疯狂iOS
iOS11适配:关于UITableView的偏移问题记录

iOS11适配:关于UITableView的偏移问题记录

作者: Jabber_YQ | 来源:发表于2017-11-15 14:49 被阅读866次

实验记录

// AppDelegate
self.window.rootViewController = [[ViewController alloc] init];

// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
vc.bouns && 无navbar.png

没有NavBar,没有设置任何东西,最简单情况。左边为iOS 8,右边为iOS 11。发现iOS 8没有向下偏移,iOS 11向下偏移了20像素。
在iOS 11中决定tableView的内容与边缘距离的是adjustedContentInset属性。
在iOS 11中,新增了安全区域的概念。由于顶部有状态栏,所以系统会自动计算出tv.adjustedContentInset值为{20, 0, 0, 0}。从而使得了tv向下偏移20像素。

// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
vc.bouns && 有navbar.png
两者都向下偏移64像素。
在iOS 11以下,控制器有automaticallyAdjustsScrollViewInsets属性,默认为YES。
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets 
API_DEPRECATED("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES

这个属性设置为YES时,系统会自动把tv向下偏移。
而在iOS 11中,可以看到automaticallyAdjustsScrollViewInsets属性被废弃,但是为什么仍然向下偏移了64像素呢。原因和一一致,现在的安全区域已经变成了NavBar以下,tv.adjustedContentInset被改为了{64, 0, 0, 0},因此也向下偏移64。

// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self; 
tv.dataSource = self;
[self.view addSubview:tv];
self.automaticallyAdjustsScrollViewInsets = NO;
vc.bouns && 有navbar && automaticallyAdjustsScrollViewInsets = NO.png
三是二的反例。设置了self.automaticallyAdjustsScrollViewInsets = NO;,iOS 11以下不偏移了。

// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

// ViewController
self.tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tv.delegate = self;
self.tv.dataSource = self;
[self.view addSubview:self.tv];
        
if (@available(iOS 11.0, *)) {
    self.tv.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
    self.automaticallyAdjustsScrollViewInsets = NO;
}
vc.bouns && 有navbar && automaticallyAdjustsScrollViewInsets = NO && UIScrollViewContentInsetAdjustmentNever.png

通过设置tv.contentInsetAdjustmentBehaviorUIScrollViewContentInsetAdjustmentNever,可以不让系统计算adjustedContentInset值。从而使得tv不再偏移。

// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

// ViewController
self.navigationController.navigationBar.hidden = YES;

self.view.backgroundColor = [UIColor yellowColor];

self.tv = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height - 64) style:UITableViewStylePlain];
self.tv.delegate = self;
self.tv.dataSource = self;
[self.view addSubview:self.tv];
y = 64 && hidden NavBar.png
有时候需要自定义导航控制器,这个时候需要把自带的NavBar隐藏。发现在iOS 11以下系统中,tv还是会偏移,并且偏移20像素。而iOS 11就没有问题。
解决办法仍然是设置automaticallyAdjustsScrollViewInsets 为NO。

iOS 11之前的 automaticallyAdjustsScrollViewInsets

我发现这个属性很有意思。

1 无NavBar

没有设置NavigationController的时候,也就是不存在NavBar的时候,这个属性不会起到作用,tv不会存在偏移问题。

2 有NavBar

2.1 显示NavBar

当设置了NavigationController的时候,并不隐藏NavBar,会默认向下偏移64像素。并且是不管你的NavBar是否遮挡住了tv,都会偏移。下图tv.y = 64


tv,y = 64.png

2.2 不显示NavBar

当设置了NavigationController的时候,并隐藏NavBar,会默认向下偏移20像素。并且和2.1一致,无论tv的frame如何,都会偏移。下图tv.y = 64


tv,y = 64 隐藏NavBar.png

如果你嫌这个属性麻烦,就设为NO,然后手动管理tv的frame。

总结

经过上面的实验,个人认为,有一个比较好的解决UIScrollView偏移问题的方法。就是在代码中加上下面这一段代码:

if (@available(iOS 11.0, *)) {
    self.tv.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
    self.automaticallyAdjustsScrollViewInsets = NO;
}

这样你就可以为所欲为了,科科。

相关文章

网友评论

  • myk:看到最后虎躯一震,叫我名字:smile:
  • 啊哈呵:从ios7开始了弄了透明的navbar,就开始各种这个偏移的设置:
    1、ViewController的automaticallyAdjustsScrollViewInsets
    2、导航栏半透明navigationBar.translucent
    3、UIScrollView的adjustedContentInset
    4、到ios11的contentInsetAdjustmentBehavior,
    各个版本的适配导航栏问题一直没有整明白,我每次有这种问题时候,都是拿这些点乱搞一通,看看那个能解决问题。
    啊哈呵:@Jabber_YQ 好的,记住这里有秘籍,等再次遇到这问题再回来看看:smile:
    Jabber_YQ:@啊哈呵 我前面还有一片文章也是讲这个的,你可以看看
    Jabber_YQ:@啊哈呵 那这次呢:joy:会用了吗
  • 思念那年慕云:说下个人的理解:
    automaticallyAdjustsScrollViewInsets
    字面意思是:自动调整scrollview的insets应该指的就是contentInset,
    tableview和collectionview都继承自scrollview
    所以有导航时偏移64,
    有导航,隐藏时,实际上有导航时,导航上面有20间距是状态栏,隐藏了导航,但20间距仍然存在。所以偏移了20.
    Jabber_YQ:@思念那年慕云 了解!谢谢:relaxed:
    思念那年慕云:@Jabber_YQ automaticallyAdjustsScrollViewInsets的官方文档: which lets container view controllers know that they should adjust the scroll view insets of this view controller’s view to account for screen areas consumed by a status bar, search bar, navigation bar, toolbar, or tab bar.
    Jabber_YQ:可是奇怪的是,当不存在导航条时,它就不会偏移了,即使遮住了状态栏。

本文标题:iOS11适配:关于UITableView的偏移问题记录

本文链接:https://www.haomeiwen.com/subject/xfhcvxtx.html