UITableView
sectionHeaderView/sectionFooterView
以前直接使用 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { }
和 func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { }
可以直接设置 sectionHeaderView 的 header 高度和 sectionFooterView 高度。
在iOS11中,只写出这两个返回高度的方法不会进行执行,因为这是不规范的写法,只写出了header/footer的高度而没有实现header/footer的view,此时会直接使用预估高度。
解决方法有两种:
- 添加返回section的headerView/footerView,返回nil
1 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { |
1 | func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { |
- 关闭header/footer预估高度,此时也会执行对应的高度方法
1 | tableView.estimatedSectionHeaderHeight = 0 |
UIBarButtonItem
距离和边界调整UIBarButtonSystemItem.fixedSpace
首先UIBarButtonItem
设置宽度必须大于0,否则失效。也就是说之前那种使用UIBarButtonSystemItem.fixedSpace
类型的item来设置负数宽度,调整距离的方法失效了,不可以在使用负值。如果再需要调整边界,建议使用customView
创建item
,去调整customView
的内部布局
planText类型的Item
1 | UIBarButtonItem.init(title: <#T##String?#>, |
这种直接使用字符串创建的UIBarButtonItem,在iOS11上点击的效果不再与之前相同(明显的点击变大)
解决方式:
- 可以将其改成使用customView
item.setTitleTextAttributes(attributes, for: UIControlState.highlighted)
navgation
自定义的titleView
自定义的titleView高度不可以超过navigationBar的高度,现在将会被强制截取navigationBar范围内的像素进行显示(类似于设置了layer.masksToBounds)
解决方法,建议将高度超过navigationBar高度的view添加到navigationController的view上进行显示,不设置为titleView
UISearchController
官方不建议在 iOS11 中直接 present SearchController,建议使用navigationItem
的searchController
的方式。
1 | if #available(iOS 11, *) { |
LargeTitle
1 | // 设置是否使用大标题 |
UIToolbar
UIToolBar不可以直接使用addSubview像其内部添加button这种方式了。
以前可以直接添加button而不必需使用UIBarButtonItem。现在直接添加subview会出现无法点击,因为现在toolbar会有一个contentview在顶层,使得下层view事件无法触发。而item也在iOS11中被添加到contentview之中。
解决方法,使用系统的api:bar.setItems([item1, item2,...], animated: true)
ViewController和ScrollView
automaticallyAdjustsScrollViewInsets
在iOS11废弃
1 | @property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets |
在iOS 11中决定tableView的内容与边缘距离的是adjustedContentInset
属性,不再是之前的contentInset。
safeArea
iOS11中,系统根据safeArea进行调整view的偏移,safeArea
safeAreaInsets
: UIView的属性,UIEdgeInsets类型,表示View距离safeArea的边界距离func safeAreaInsetsDidChange()
: UIView方法,会在安全区域被改变时调用。additionalSafeAreaInsets
: UIViewController的属性,UIEdgeInsets类型,扩展系统默认的safeArea (UIEdgeInsets.init(top: t, left: l, bottom: b, right: r),向内部缩小t/l/b/r的距离)
adjustedContentInset
readonly, UIEdgeInsets
adjustedContentInset
表示 contentView.frame.origin
偏移了 scrollview.frame.origin
多少;是系统计算得来的,计算方式由 contentInsetAdjustmentBehavior
决定。
contentInsetAdjustmentBehavior
1 | public enum UIScrollViewContentInsetAdjustmentBehavior : Int { |
摘自腾讯bugly技术文档
automatic
:如果scrollview
在一个automaticallyAdjustsScrollViewInsets = true
的controller
上,并且这个controller
包含在一个navigationController
中,这种情况下会设置在top
&bottom
上adjustedContentInset = safeAreaInset + contentInset
不管是否滚动。其他情况下与UIScrollViewContentInsetAdjustmentScrollableAxes
相同scrollableAxes
: 在可滚动方向上adjustedContentInset = safeAreaInset + contentInset
,在不可滚动方向上adjustedContentInset = contentInset
;依赖于scrollEnabled
和alwaysBounceHorizontal/Vertical = YES
,scrollEnabled
默认为true
,所以大多数情况下,计算方式还是adjustedContentInset = safeAreaInset + contentInset
never
:adjustedContentInset = contentInset
always
:adjustedContentInset = safeAreaInset + contentInset
当contentInsetAdjustmentBehavior
设置为never
的时候,adjustedContentInset
值不受safeAreaInset
值的影响。
一些新的高度
\ | 以前的iPhone | iPhone X |
---|---|---|
statusBar | 20 | 44 |
navigationBar | 44 | 44 |
tabBar | 49 | 83 |
第三方库MJRefresh
因为MJRefresh已经停止维护很久了。目前受影响的是使用automaticallyAdjustsScrollViewInsets的ViewController中的scrollView(tableView),可以使用下面方式解决。
1 | if #available(iOS 11.0, *) { |
update 9.28
MJRefresh
(Github Link)更新了新版本3.1.13
,适配了iOS11和Xcode9,可不再使用上述方法。