欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

我的iOS11及iPhoneX适配(一)

程序员文章站 2024-03-23 08:09:04
...

我做的项目,在更新xcode到9.0,sdk版本是iOS11,如果不适配,暂时发现以下问题:

1.

我的iOS11及iPhoneX适配(一)







2

我的iOS11及iPhoneX适配(一)



3

我的iOS11及iPhoneX适配(一)





以下是解决方案:


问题1:问题原因是iOS 11中Controller的automaticallyAdjustsScrollViewInsets属性被废弃了,所以当tableView超出安全区域时系统自动调整了SafeAreaInsets值,进而影响adjustedContentInset值,在iOS 11中决定tableView的内容与边缘距离的是adjustedContentInset属性,而不是contentInset。因为系统对adjustedContentInset值进行了调整,所以导致tableView的内容到边缘的距离发生了变化,导致tableView下移了20pt(statusbar高度)或64pt(navigationbar高度)。


因此,我们来看看adjustedContentInset的计算方式:

Default is UIScrollViewContentInsetAdjustmentAutomatic. 
*/@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior 
adjustContentInset表示contentView.frame.origin偏移了scrollview.frame.origin多少;是系统计算得来的,计算方式由contentInsetAdjustmentBehavior决定。有以下几种计算方式:

1.UIScrollViewContentInsetAdjustmentAutomatic:如果scrollview在一个automaticallyAdjustsScrollViewContentInset = YES的controller上,并且这个Controller包含在一个navigation controller中,这种情况下会设置在top & bottom上 adjustedContentInset = safeAreaInset + contentInset不管是否滚动。其他情况下与UIScrollViewContentInsetAdjustmentScrollableAxes相同

2.UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滚动方向上adjustedContentInset = safeAreaInset + contentInset,在不可滚动方向上adjustedContentInset = contentInset;依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES,scrollEnabled默认为yes,所以大多数情况下,计算方式还是adjustedContentInset = safeAreaInset + contentInset

3.UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset

4.UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset

当contentInsetAdjustmentBehavior设置为UIScrollViewContentInsetAdjustmentNever的时候,adjustContentInset值不受SafeAreaInset值的影响。

解决方法:

网上的方法有好几种,我用的是以下方法:

设置tableView的contentInsetAdjustmentBehavior属性

如果不需要系统为你设置边缘距离,可以做以下设置:

 //如果iOS的系统是11.0,会有这样一个宏定义“#define __IPHONE_11_0  110000”;如果系统版本低于11.0则没有这个宏定义#ifdef __IPHONE_11_0   
if ([tableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
    tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
#endif

contentInsetAdjustmentBehavior属性也是用来取代automaticallyAdjustsScrollViewInsets属性的,推荐使用这种方式。

另外,对于tableview的section之前的间隔问题,是由于在创建tableview的时候,设置了UITableView的style为UITableViewStyleGrouped,默认tableView开头和结尾是有间距的,不需要这个间距的话,可以通过实现heightForHeaderInSection方法(返回一个较小值:0.1)和viewForHeaderInSection(返回一个view)来去除头部的留白,底部同理。代码中只实现了heightForHeaderInSection方法,而没有实现viewForHeaderInSection方法。那样写是不规范的,只实现高度,而没有实现view,但代码这样写在iOS 11之前是没有问题的,iOS 11之后应该是由于开启了估算行高机制引起了bug。添加上viewForHeaderInSection方法后,问题就解决了。或者添加以下代码关闭估算行高,问题也得到解决。

解决方法是:

    _tableView.estimatedRowHeight = 0;

    _tableView.estimatedSectionHeaderHeight = 0;

    _tableView.estimatedSectionFooterHeight = 0;


对于问题2,也同样是这个问题。


问题3:对于这个问题,我也很奇怪,感觉这个跟升级了iOS11关系不大,但是看了代码,才知道问题

- (void)deleteBtnAction:(UIButton *)sender {
    UITableViewCell *cell = (UITableViewCell *)[[sender superview] superview];
    UITableView *tableView = (UITableView *)[[cell superview] superview];
    NSIndexPath *path = [tableView indexPathForCell:cell];
    
    
    [self.delegate clickDeleteBtnActionAssertModifyCell:path];
}


- (void)editBtnAction:(UIButton *)sender {
    UITableViewCell *cell = (UITableViewCell *)[[sender superview] superview];
    UITableView *tableView = (UITableView *)[[cell superview] superview];
    NSIndexPath *path = [tableView indexPathForCell:cell];
    
    
    [self.delegate clickEditBtnActionAssertModifyCell:path];
}

原来之前的代码是在button响应事件中取到NSIndexPath,在通过delegate回调,虽然这个逻辑不是很好,但是在之前的版本也没问题,但是在iOS11中,貌似页面的分层有变化,导致[[cell superview] superview]直接crash。

我给的解决办法是:

1、直接在cell新加block属性,在点击buttoon的时候,调用block,通过block中的NSIndexPath直接得到。

2、修改原代码delegate的参数,之间返回cell本身的self,在回调delegeate的tableview页面通过cell直接取到NSIndexPath,避免了现在的层层向上找superview的方法。

最终代码是:

- (void)deleteBtnAction:(UIButton *)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(clickDeleteBtnActionAssertModifyCell:)]) {
        [self.delegate clickDeleteBtnActionAssertModifyCell:self];
    }
}


- (void)editBtnAction:(UIButton *)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(clickEditBtnActionAssertModifyCell:)]) {
        [self.delegate clickEditBtnActionAssertModifyCell:self];
    }
}


在调用的地方,代码是:

// 删除

- (void)clickDeleteBtnActionAssertModifyCell:(TLQAssertModifyCell *)cell {

NSIndexPath *index = [identifyTableView indexPathForCell:cell];

// todo

}