星期

2020年04月29日

博客 - CocoaChina

2020-04-29 05:47:54 来源:互联网 阅读:-

一.bug展示

Xcode 升级到 版本后,公司中的项目运行到iOS11的设备上出现了一个UI Bug,原来自动适配tableview的内间距失效了. 很显然,tableView有了额外的内边距.代码运行到之前的环境上是没问题的,可用Xcode9一编译,再跑到iOS11上就会出现问题...

二.问题产生原因

先贴一段设置tableView的代码

private func setupTableView() { tableView = UITableView() tableView.frame = view.bounds tableView.dataSource = self tableView.delegate = self tableView.backgroundColor = UIColor.red extendedLayoutIncludesOpaqueBars = true; automaticallyAdjustsScrollViewInsets = false; // 设置tableView的内边距(能够显示出导航栏和tabBar下覆盖的内容) tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0) // 设置内容指示器(滚动条)的内边距 tableView.scrollIndicatorInsets = tableView.contentInset } 关于extendedLayoutIncludesOpaqueBars和automaticallyAdjustsScrollViewInsets

这两个属性属于UIViewController 默认情况下extendedLayoutIncludesOpaqueBars = false 扩展布局不包含导航栏 默认情况下automaticallyAdjustsScrollViewInsets = true 自动计算滚动视图的内容边距 但是,当 导航栏 是 不透明时,而tabBar为透明的时候,为了正确显示tableView的全部内容,需要重新设置这两个属性的值,然后设置contentInset(参考代码). 上面的代码逻辑没有问题,但是放到iOS11 上为啥错了呢? 找了半天,点开了automaticallyAdjustsScrollViewInsets 这个属性,发现这个属性在iOS11过期了,如图:

在OC的声明中,这个属性是这样的: @property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(),tvos()); // Defaults to YES 这说明在iOS11 中, UIViewController的automaticallyAdjustsScrollViewInsets属性已经不再使用,我们需要使用UIScrollView的 contentInsetAdjustmentBehavior 属性来替代它.

关于contentInsetAdjustmentBehavior

@available(iOS 11.0, *) public enum UIScrollViewContentInsetAdjustmentBehavior : Int {

case automatic // Similar to .scrollableAxes, but will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewContentInset = YES inside a navigation controller, regardless of whether the scroll view is scrollable

case scrollableAxes // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)

case never // contentInset is not adjusted

case always // contentInset is always adjusted by the scroll view's safeAreaInsets

} UIScrollViewContentInsetAdjustmentBehavior 是一个枚举类型,值有以下几种:

automatic 和scrollableAxes一样,scrollView会自动计算和适应顶部和底部的内边距并且在scrollView 不可滚动时,也会设置内边距. scrollableAxes 自动计算内边距. never不计算内边距 always 根据safeAreaInsets 计算内边距 很显然,我们这里要设置为 never 三.开始适配

swift 中

private func setupTableView() { tableView = UITableView() tableView.frame = view.bounds tableView.dataSource = self tableView.delegate = self tableView.backgroundColor = UIColor.red

    extendedLayoutIncludesOpaqueBars = true;
    if #available(iOS 11.0, *) {
        tableView.contentInsetAdjustmentBehavior = .never
    } else {
        automaticallyAdjustsScrollViewInsets = false;
    };
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0)
    tableView.scrollIndicatorInsets = tableView.contentInset

} OC 中

self.extendedLayoutIncludesOpaqueBars = YES; if (@available(iOS 11.0, *)) { self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } else { self.automaticallyAdjustsScrollViewInsets = NO; } _tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0); _tableView.scrollIndicatorInsets = _tableView.contentInset;

推荐阅读:广西在线