iOS11-&-iPhone-X-适配之路

适配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;
    }

效果

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

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

下拉刷新

很多人都遇到下拉刷新错位的问题,我们项目中也遇到了,直接不能用,很伤心,这是与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


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


获取 SafeArea

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

未完,持续更新~

参考文章链接

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

你可能感兴趣的:(iOS)