最近更新了iOS11的版本,发现一些修改的地方影响的比较严重,结合网上的一些资料,在此做一个汇总
- tableview内容偏移
- cell侧滑
1 tableview内容偏移
在此之前,首先解释一下一个控制器的属性automaticallyAdjustsScrollViewInsets
automaticallyAdjustsScrollViewInsets,当设置为YES时(默认YES),如果视图里面存在唯一一个UIScrollView或其子类View,那么它会自动设置相应的内边距,这样可以让scroll占据整个视图,又不会让导航栏遮盖。
也就是加载完成后,真实显示出的内容会出现向下偏移,一般是64或者84(打电话)或者20(无navbar导航栏)。
内容与边界的距离
在UITableView和UItableViewCell之间有一个UITableViewWrapperView层(注:在iOS11中,该层已经消失)
两个层顶部相差一定的距离(64/84/20/···)
解决这个问题很简单,只要把控制器的 automaticallyAdjustsScrollViewInsets设置成NO即可。也就是说不要自动布局。
1 |
self.automaticallyAdjustsScrollViewInsets = NO; |
不幸的是,iOS11废弃了此方法。
在OC的声明中,这个属性是这样的:
1 2 3 4 |
// Defaults to YES @property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); |
这说明在iOS11中, UIViewController的automaticallyAdjustsScrollViewInsets属性已经失效
需要使用UIScrollView的 contentInsetAdjustmentBehavior 属性替代.
由于automaticallyAdjustsScrollViewInsets是iOS11新增的方法。因此在使用时需要判断
1 2 3 4 5 |
if (@available(iOS 11.0, *)) { tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); tableView.scrollIndicatorInsets = _tableView.contentInset; } |
2 cell侧滑
IOS更新后,侧滑控件的位置从CELL内部移动到与CELL平级的层级中
iOS10 侧滑控件在cell内
1 2 3 4 5 6 7 8 9 10 11 12 |
// iOS11之前的方法,在cell中重写此方法,可以监控到侧滑菜单的压入 //Rewrite - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index { [super insertSubview:view atIndex:index]; if ([view isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) { for (UIButton *btn in view.subviews) { btn.titleLabel.font = [UIFont systemFontOfSize:15]; // .... } } } |
iOS8~iOS10的侧滑菜单属于cell的子视图,并且每个按钮都是独立的。
但是iOS11中,侧滑的控件不仅仅变成跟cell平级,而且多个按钮之间也是叠加的状态
iOS10 结构 图六, 可以看到每个按钮分开的
iOS11的cell,新增的方法中可以添加图片了。如果需要修改一些参数,需要在tableView的代理方法中开始重绘。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
- (void)viewDidLayoutSubviews{ [super viewDidLayoutSubviews]; if (self.swipeIndexPath){ [self refreshSwipeButton:(self.swipeIndexPath)]; } } // 修改的代码 - (void) refreshSwipeButton:(NSIndexPath *)swipeIndexPath{ // 获取选项按钮的reference if (@available(iOS 11.0, *)) { // iOS11 层级 (Xcode 8编译): UITableView -> UITableViewWrapperView -> UISwipeActionPullView for (UIView *subview in self.tableView.subviews){ if ([subview isKindOfClass:NSClassFromString(@"UITableViewWrapperView")]){ for (UIView *subsubview in subview.subviews){ // update code } } } }else{ // iOS 8-10层级: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView // 侧滑控件属于cell的子控件 UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:swipeIndexPath]; for (UIView *subview in cell.subviews){ // update code } } } - (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath { self.swipeIndexPath = indexPath; // 重绘 [self.view setNeedsLayout]; } |