iOS 11适配问题

今天稍微闲了点,就升级了一个iOS11,看下项目在11下是否健壮,然而却遇到了一些问题,简单记录下。

1.直接崩溃在Main函数,报错信息如下。

exception 'NSInternalInconsistencyException'
reason: 'attempt to delete section 2, but there are only 1 sections before the update'

断点分析是tableView的reloadSections出现的问题。原因是在iOS11中默认开启Self-Sizing 包括Headers, footers,导致section定位不准确,如果你没用到预估高度 那么你尝试在Appdelegate.m中的didFinishLaunchingWithOptions方法中,加上如下代码

if (@available(iOS 11.0, *)) {
    [[UITableView appearance] setEstimatedRowHeight:0];
    [[UITableView appearance] setEstimatedSectionHeaderHeight:0];
    [[UITableView appearance] setEstimatedSectionFooterHeight:0];
}

如果继续崩溃,那就要在具体的tableView设置了

2.地图权限未获取到,控制台会有警告信息

This app has attempted to access privacy-sensitive data without a usage description. 
The app's Info.plist must contain both NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription keys with string values explaining to the user how the app uses this data

iOS 11中对部分权限名称做了修改,需要改动plist文件

NSLocationAlwaysUsageDescription 对应修改为 NSLocationAlwaysAndWhenInUseUsageDescription

相册需要添加 NSPhotoLibraryAddUsageDescription(注:是添加,原有NSPhotoLibraryUsageDescription保留,如果替换,打包上传会被认定为无效文件

3.部分tableView界面下拉刷新偏移,我的一个界面下拉刷新后多出大约20的偏移。

iOS11弃用了automaticallyAdjustsScrollViewInsets属性,新增contentInsetAdjustmentBehavior来替代它

// 添加下面代码  
if (@available(iOS 11.0, *)) {  
    _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;  
    _tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);  
    _tableView.scrollIndicatorInsets = _tableView.contentInset;  
}

4.navigationItem.titleView居中显示了,如果是一个搜索框,就很难看了
iOS 11 中改变了UINavigationBar的视图层级,titleView不是加到NavigationBar上了,而是加到UINavigationBarContentView上 我们需要在自定义的View中重写下面的方法

- (CGSize)intrinsicContentSize
{
    return UILayoutFittingExpandedSize;
}

5.在iOS11.0.2的系统中(目前已知这一个)使用
[[UIApplication sharedApplication].windows lastObject有坑,默认获取此对象,它的hidden属性为YES,如果在此上添加界面会无法显示。可以改为 [[UIApplication sharedApplication].delegate window] 或者设置hidden为NO