iOS11适配---你可能没注意的问题与解决方案

有种后知后觉的感觉,�iOS11已经出来半个多月了,本来觉得不需要做太多的适配,我把适配的重点放到了新出的机型iPhoneX上。但是在适配iPhoneX的过程中,突然发现了很多诡异的现象。然后我把注意力又拉回了iOS11的适配,在这几天的适配中,处理了几个问题,后续的问题还会在追踪中。下面的例子我都以iPhoneX的模拟器上演示了,后续也会出iPhoneX的布局适配方案文章。

问题1:tableView莫名其妙的在上拉加载的时候乱跳

适配前:

关注页面适配前.gif

适配之前如上图,在上拉加载之后,tableView在加载完毕之后,并没有恢复到正常的位置,但是在iOS11以下都是正常的,如果仅仅是没有恢复到原有位置也就算了,MJRefresh同时还在不停的触发上拉加载方法,不停的在请求网络,刚开始我第一反应以为是iPhoneX的问题,但是后来发现不是的,只要是iOS11以上,都会出现这样的问题。第二反应以为是界面架构问题,由于这个界面相对复杂,我刚开始以为是因为collectionView嵌套tableView的原因,后来看普通的列表页也会出现这样的问题。最后定位了问题,发现问题的根本原因在这里:
在iOS11 中, UIViewController的automaticallyAdjustsScrollViewInsets属性已经不再使用,我们需要使用UIScrollView的 contentInsetAdjustmentBehavior 属性来替代它.

再来看一下 这个属性的内部结构

@available(iOS 11.0, *)
public enum UIScrollViewContentInsetAdjustmentBehavior : Int {

    case automatic // Similar to .scrollableAxes, but will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewContentInset = YES inside a navigation controller, regardless of whether the scroll view is scrollable

    case scrollableAxes // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)

    case never // contentInset is not adjusted

    case always // contentInset is always adjusted by the scroll view's safeAreaInsets
}

automatic 和scrollableAxes一样,scrollView会自动计算和适应顶部和底部的内边距并且在scrollView 不可滚动时,也会设置内边距.
scrollableAxes 自动计算内边距.
never不计算内边距
always 根据safeAreaInsets 计算内边距

这里我们需要把这个属性禁用调,不然系统会帮我们自动计算内边距,这样在滚动之后无法定位。

解决方案:我相信大多数人和我一样,项目内有大量的UIScrollView,UITableView和UICollectionVIew的一种或者多种,不可能在每次初始化的时候去单独处理这个属性。不过好在这几个控件都是遵循appearance
代理的,我们可以在项目初始化的时候,对此类控件进行全局统一设置。

#pragma mark - 适配iOS11以上 scrollview 乱序滚动问题
- (void)adaptateIOS11{
    //适配iOS11以上UITableview 、UICollectionView、UIScrollview 列表/页面偏移
    if (@available(iOS 11.0, *)){
        [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
    }
}

这样你项目内部初始化的三类控件都会默认禁止调ContentInsetAdjustmentBehavior 这个属性。按道理来说,应该问题可以得到解决了。但是以上问题还存在。我们之前的步骤只解决了第一步问题。在禁止ContentInsetAdjustmentBehavior这个属性之后,我们还需要设置3条预设高度。

最终解决方案:

#pragma mark - 适配iOS11以上 scrollview 乱序滚动问题
- (void)adaptateIOS11{
    //适配iOS11以上UITableview 、UICollectionView、UIScrollview 列表/页面偏移
    if (@available(iOS 11.0, *)){
        [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];

        [[UITableView appearance] setEstimatedRowHeight:0];
        [[UITableView appearance] setEstimatedSectionFooterHeight:0];
        [[UITableView appearance] setEstimatedSectionHeaderHeight:0];
    }
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
  
    [self adaptateIOS11];

    return YES;
}

然后在AppDelegate启动项目时,调用该方法。

关注页面适配后.gif

最终适配效果恢复正常了。
在解决这个问题的时候,发现有人说还有几个问题,不过暂时没有全部遇到,把解决方案放到下面,可以自行选择

tableview 适配

 1. 滚动条乱跳问题解决:
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;


2. 列表位置错误问题解决:
先查看tableView的frame是否正常,然后设置下面属性
if (@available(iOS 11.0, *)){
_tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
_tableView.contentInset = UIEdgeInsetsMake(0, 0, 49, 0);//top 和 bottom根据使用场景灵活设置
_tableView.scrollIndicatorInsets = _tableView.contentInset;
}


3. 
使用scrollview的地方出现布局错位 跳动等问题解决:

你的scrollview.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

问题2:奇怪的UITableView分割线问题

iOS11之后,我们的项目内的UITableView莫名其妙的Cell的头部和底部在某些界面多了很多特别明显的灰色的分割线。
适配前:

首页线条适配前.jpeg
我的界面适配前.jpeg

如上图,在我回去看这些界面的tableview的时候,都发现了一个特点这几个tableview的分割线类别都使用了tableView.separatorStyle=UITableViewCellSeparatorStyleSingleLineEtched;

再看一下separatorStyle这个属性有什么变化

typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) {
    UITableViewCellSeparatorStyleNone,
    UITableViewCellSeparatorStyleSingleLine,
    UITableViewCellSeparatorStyleSingleLineEtched NS_ENUM_DEPRECATED_IOS(2_0, 11_0, "Use UITableViewCellSeparatorStyleSingleLine for a single line separator.")
} __TVOS_PROHIBITED;

解决方案:

UITableViewCellSeparatorStyleSingleLineEtched 在iOS11之后废弃了,让使用UITableViewCellSeparatorStyleSingleLine代替,或者自定义。起初UITableViewCellSeparatorStyleSingleLineEtched在iOS11以下是和UITableViewCellSeparatorStyleNone效果是一样的,没有分割线。但是在iOS11以上。如果不需要分割线,必须使用UITableViewCellSeparatorStyleNone。在把这些界面的分割线类别都修改为UITableViewCellSeparatorStyleNone之后,问题得到了解决。

问题3: UIBarButtonItem 如果为纯文字展示,长按按钮进入高亮状态会出现系统蓝色

问题效果图如下图gif:

barItem适配前.gif

只有iOS11以上的,纯文字的按钮,会出现这样的问题。我查看了初始化代码。

 /*
         取消按钮
         */
        UIBarButtonItem * leftItem=[[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(leftBtnClick)];
        NSMutableDictionary * leftItemAttrs = [NSMutableDictionary dictionary];
        leftItemAttrs[NSForegroundColorAttributeName] = Color_Text_Gray_80;
        leftItemAttrs[NSFontAttributeName] = [OWFont systemFontOfSize:FontSize_15];
        [leftItem setTitleTextAttributes:leftItemAttrs forState:UIControlStateNormal];
        self.navigationItem.leftBarButtonItem = leftItem;

我猜测是我仅仅设置了normal状态的原因,但是该处理方式在iOS11以下并不会有问题。所以我在下方又添加了高亮状态,果然就解决了。

解决方案:

 /*
         取消按钮
         */
        UIBarButtonItem * leftItem=[[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(leftBtnClick)];
        NSMutableDictionary * leftItemAttrs = [NSMutableDictionary dictionary];
        leftItemAttrs[NSForegroundColorAttributeName] = Color_Text_Gray_80;
        leftItemAttrs[NSFontAttributeName] = [OWFont systemFontOfSize:FontSize_15];
        [leftItem setTitleTextAttributes:leftItemAttrs forState:UIControlStateNormal];
       //适配iOS11
        [leftItem setTitleTextAttributes:leftItemAttrs forState:UIControlStateHighlighted];
        self.navigationItem.leftBarButtonItem = leftItem;

下面我先仅适配了左侧取消按钮 没有适配右侧按钮 可以看一下对比

barItem适配后.gif

问题4:UITableView 顶部多出一部分空白区域

tableview顶部空白问题.jpeg

如图,我突然发现在某些界面tabview的顶部会多出来一部分空白区域,并不是我设置的高度。出现问题的界面都有一个特点,都是单纯指定了sectionHeader的高度,但是并没有返回一个sectionHeaderView.这种写法在iOS11之前是可以正常展示的,但是在iOS11上,系统会预先设置一个sectionheaderView进去,如果你不执行返回sectionHeader的代理.

解决方案:

#pragma mark 此方法加上是为了适配iOS 11出现的问题

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    return nil;
}
//有时候tableview的底部视图也会出现此现象对应的修改就好了
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
    return nil;
}

如果你设置了sectionHeader的高度的话,同时并不需要设置一个具体的view,那么你也需要执行一下上面的代理,返回一个nil就可以了。补充完代码之后,诡异的高度消失了

问题5:iOS11定位失效

这点也是我在之前看适配问题的时候,大概有注意过有人说过这个问题,但是并没有去测试。昨天我在看我们的定位功能的时候,确实发现iOS11下,获取用户地理位置的时候没有反应了。然后我查阅了相应的文章。发现iOS11之后,苹果对获取用户的地理位置权限进行了改动。

苹果现在增加了一项新的隐私保护功能 NSLocationAlwaysAndWhenInUseUsageDeion
并且原有的 NSLocationAlwaysUsageDeion 被降级为 NSLocationWhenInUseUsageDeion

解决方案:

想要达到之前 NSLocationAlwaysUsageDeion 的定位效果,需要在info.plist文件中添加 NSLocationAlwaysAndWhenInUseUsageDeion 和 NSLocationWhenInUseUsageDeion 两个就可以了。否则,徒劳无功,你的App依旧不支持Always authorization。

并且新的用户授权选择更为人性化。你如果遇到了这个问题可以修改之后去看一下最终的效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 苹果公司于9月份如期发布了新的iPhone-iPhone8,iPhone8 Plus,iPhoneX,前两个不用多...
    MonkeyHeng阅读 8,611评论 5 43
  • 经常在调试服务端返回 JSON 结果的时候遇到Unicode 编码的表示方法: 从网络上获得的unicode码的开...
    emily_sky阅读 6,383评论 2 2
  • 我最近最想实现的目标是三个月内收入增长一倍,并看到儿子具足智慧,学业有成。所以我咖啡冥想的内容: 1.慷慨大度的种...
    叶景芳阅读 115评论 0 1
  • 《思考快与慢》系列10 1. 最近一直都在读《思考快与慢》,这本书告诉了我们详细的思考过程。我们要启动系统二、即调...
    薇莉不罔不怠阅读 620评论 0 0
  • 1.自带投影功能 手指滑动键盘,键盘可以投影到桌子等地方,可以缩放,方便敲打。滑动屏幕上播放的视频或照片移到墙...
    SunnnnYR_阅读 313评论 0 0