每年的WWDC大会都激动和紧张好一段时间。激动的是期待苹果的新产品带来的那些黑科技,尤其今年的iPhone10周年纪念款iPhone X。紧张的当然是iOS、Swift和Xcode的升级,又要加班了(ㄒoㄒ)。在这里跟大家分享一下适配iOS 11和iPhone X的过程中,遇到了一些坑。
一、导航栏
在解释导航栏变化之前先解释一个iOS 11的新特性:设置大标题,通过BOOL类型的prefersLargeTitles属性来设置。默认设置是不开启。
//显示大标题“设置”
self.navigationController.navigationBar.prefersLargeTitles = YES;
self.navigationItem.title = @"设置";
简书1.png
其中LargeTitle还有三种样式可以选择:
UINavigationItemLargeTitleDisplayModeNever//总是显示小标题
UINavigationItemLargeTitleDisplayModeAlways//总是显示大标题
UINavigationItemLargeTitleDisplayModeAutomatic//自动显示大标题或小标题。即初始时是大标题,滑动时大标题隐藏、显示小标题。
通过navigationItem的largeTitleDisplayMode属性来设置:
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;
当然,只有当prefersLargeTitles为YES时largeTitleDisplayMode属性才生效,
1、导航栏高度变化
iOS 11之前导航栏默认高度为64pt(statusBar + NavigationBar),iOS11之后如果设置了prefersLargeTitles = YES则为96pt,默认情况下还是64pt。由于iPhoneX上出现了“刘海”,statusBar由以前的20pt变成了44pt,所以iPhoneX上高度变为88pt。
2、导航栏图层变化
iOS 11之前导航栏的title是添加在UINavigationItemView上面的,而navigationBarButton则是直接条件在navigationBar上面。如果设置了titleView,那么titleView也是直接添加在navigationBar上面的。
简书2.png
iOS 11之后,视图层级发生了变化,增添了新的管理类。navigationBar会添加在_UIButtonBarStackView上面,而_UIButtonBarStackView则添加在_UINavigationBarContentView上面。如果没有给titleView赋值,那么titleView会直接添加在_UINavigationBarContentView上面;如果赋值了titlev,那么titleview会添加在_UITAMICAdaptorView上面,_UITAMICAdaptorView会添加在_UINavigationBarContentView上面。
简书3.png
简书4.png
所以如果你的项目是自定义的navigationBar,那么在iOS11上运行就可能出现布局错乱的bug,解决办法是重写UINavigationBar的layoutSubviews方法,调整布局。
- (void)layoutSubviews {
[super layoutSubviews];
//注意导航栏及状态栏高度适配
self.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), naviBarHeight);
for (UIView *view in self.subviews) {
if([NSStringFromClass([view class]) containsString:@"Background"]) {
view.frame = self.bounds;
}
else if ([NSStringFromClass([view class]) containsString:@"ContentView"]) {
CGRect frame = view.frame;
frame.origin.y = statusBarHeight;
frame.size.height = self.bounds.size.height - frame.origin.y;
view.frame = frame;
}
}
}
二、UIScrollView、UITableView、UICollectionView
在iOS 11之前,如果想要scrollView不偏移64pt,则设置automaticallyAdjustsScrollViewInsets = NO,现在iOS 11设备上运行出现最多问题应该就是tableview莫名奇妙的偏移20pt或者64pt了。原因就是iOS 11弃用了automaticallyAdjustsScrollViewInsets属性,取而代之的是UIScrollView新增的contentInsetAdjustmentBehavior属性。最终还是因为iOS 11新添了safeArea。
另外,tableView的sectionHeader、sectionFooter高度与设置不符的问题,因为在iOS 11中如果不实现
-tableView: viewForHeaderInSection:
-tableView: viewForFooterInSection:
则不会被调用
-tableView: heightForHeaderInSection:
- tableView: heightForFooterInSection:
导致sectionHeader、sectionFooter的高度都变成了默认高度。
iOS 11之前,设置sectionHeader、sectionFooter高度为0时,需要设置height=0.1,才会起作用,如果直接设置为0,则会使用默认高度。在iOS 11中默认使用Self-Sizing,tableView的estimatedRowHeight、estimatedSectionHeaderHeight、 estimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,解决办法简单粗暴,就是实现对应方法或把这三个属性设为0。
如果你使用了Masonry,那么你需要适配safeArea
if (@available(iOS 11.0, *)) {
make.edges.equalTo()(self.view.safeAreaInsets)
} else {
make.edges.equalTo()(self.view)
}
今天暂且录入这几个问题,后续继续更新
网友评论