iOS11 & iPhone X 适配之路

作者: 一蓑烟雨满眼风波 | 来源:发表于2017-09-30 18:17 被阅读202次

    适配iOS 11有几天了,这中间遇到无数种坑,由于我们项目支持iPad支持横竖屏,改起来简直想哭,好了废话不多说,总结下iOS 11&iPhone X的适配过程中遇到的问题。

    iOS 11适配

    UISearchController with Navigation

    UISearchController在iOS 11中有较大的改动,如果你项目中有用到,在Xcode 8.3上打包在iOS 11上还是可以正常使用,如果你使用Xcode9....

    横屏 竖屏

    这样玩意已经不能看了
    下面回顾下iOS 11之前是怎么添加使用的

            self.tableView.tableHeaderView = _searchController.searchBar;
    

    iOS 11 UISearchController使用在navigationItem添加了两个属性

    • navigationItem.searchController
    • navigationItem.hidesSearchBarWhenScrolling 默认为YES
      iOS 11的使用
        if (@available(iOS 11.0, *)) {
            self.navigationItem.searchController = _searchController;
        } else {
            self.tableView.tableHeaderView = _searchController.searchBar;
        }
    

    效果

    navigationItem.searchController

    现在能也可以根据滑动来隐藏SearchBar了,但是我遇到的问题不仅仅是这样的,如果你使用UISearchController下一级的页面也使用且hidesSearchBarWhenScrolling为YES,那么在执行push的时候画面会这样....


    注意push和pop过程中导航条下面会有一条留白

    这个问题很尴尬,我到现在还没有解决


    下拉刷新

    很多人都遇到下拉刷新错位的问题,我们项目中也遇到了,直接不能用,很伤心,这是与iOS 11使用新的机制有关,automaticallyAdjustsScrollViewInsets在iOS 11中被被废弃,然后在scrollerView中添加contentInsetAdjustmentBehavior一个这样的属性,为什么这个会影响到下拉刷新这个控件呢,下面我来简单的说一下。
    通常iOS 实现下拉刷新是通过KVO观察者模式,监听UIScrollerView的contentOffset属性,在该属性发生变化时,获取contentoffset的y值,比对初始contentoffset
    详情看下面的代码,简单说明下拉刷新实现部分原理

    /*
    originalInset:,原始偏移值,如果设置automaticallyAdjustsScrollViewInsets .top 偏移为navgationbar.height + statusBar.height
    contentOffset:scrollerView现在的偏移值
    headerHeight :刷新头部View的高度
    
    ps.
    originalInset = scrollView.contentInset,可以这样获取,只获取一次
    */
            CGPoint contentOffset = [[change valueForKey:NSKeyValueChangeNewKey] CGPointValue];
    
    if (originalInset.top - contentOffset.y > headerHeight) {
            //让tableView悬停,显示正在刷新View
             UIEdgeInsets inset = _scrollView.contentInset;
             insetTop.top =  originalInset.top +  headerHeight;
              _scrollView.contentInset = inset;
    }
    

    通过上面所说的automaticallyAdjustsScrollViewInsets的设置会影响到计算,iOS 11中不在使用,iOS 11 中scrollView.contentInset(初始偏移量为0),但是他又引入了一个新的属性adjustedContentInset,所有我们项目中计算出错,下拉刷新无法,往上滑触发,并进行下移,所有我对代码进行了如下修改

    cgfloat originalTop = originalInset.top;
    if  (iOS 11){
              originalTop = self.adjustedContentInset.top;
    }
    if (originalTop - contentOffset.y > headerHeight) {
             UIEdgeInsets inset = _scrollView.contentInset;
             insetTop.top =  originalInset.top +  headerHeight;
              _scrollView.contentInset = inset;
    }
    

    上面代码是我修改的思路,上拉刷新也是同样的道理

    iPhone X适配

    如果你的app不需要竖屏,那么恭喜你,减少了很多麻烦,如果需要横屏就要多费些时间了

    Safe area

    Safe area

    iPhone X的适配主要是要把可以操作的控件放到安全区域内


    获取 SafeArea

    属性
    • safeAreaInsets
      改属性可以获取安全区域 UIEdgeInsets
      切记:
      UIViewController中,safeAreaInsets在viewDidLoad之后才有值,如果你在viewDidLoad 中要使用会发现没有值
      可以通过系统方法监听SafeArea改变
    SafeArea 改变方法
    • viewSafeAreaInsetsDidChange
      UIViewController中使用
    • safeAreaInsetsDidChange
      UIView中使用,在重新设置View的Frame或横竖屏变化会调用

    UITableView适配

    • contentView
      Cell和headerView上的控件一定要放到contentView上,不然就是下面的这种情况,contentView会根据safe area自适应


      headerView
    • heightForHeaderInSection设置无效
    图片.png

    已经设置过heightForHeaderInSection 但是显示仍是这样

    图片.png

    解决方法:
    设置viewForHeaderInSection

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        return nil;
    }
    

    未完,持续更新~

    参考文章链接

    Updating Your App for iOS 11
    Designing for iPhone X
    你可能需要为你的APP适配iOS11
    刘海 |关于iPhone X 的适配

    相关文章

      网友评论

        本文标题:iOS11 & iPhone X 适配之路

        本文链接:https://www.haomeiwen.com/subject/jpxuextx.html