iOS 11 适配

1. navigationItem.titleView

iOS 11 导航栏图层以及边距的变化,导致自定义 titleView 的导航栏在 iOS 11 需要额外的适配。

iOS 11 适配_第1张图片
frame

titleView 的主要问题是之前居中的位置发生了偏移。

自定的导航栏的 titleView 是直接添加在 navigationBar 上面。在 iOS 11之后,系统添加了新的类来管理,增加了 navigationBarContentView 如果没有设置 titleView ,则 titleView 直接添加在 navigationBarContentView ; 如果设置了 titleView ,则会生成一个 UITAMICAdaptorView , titleView 会添加在这个类,这个类添加在navigationBarContentView

iOS 10及之前

iOS 11 适配_第2张图片
iOS 10

iOS 11

iOS 11 适配_第3张图片
iOS 11

之前自定义的导航栏

let titleView = BKTitleView.init(frame: ccr(0, 0, kScreenWidth - 30, 30))
titleView.center = ccp(kScreenWidth * 0.5, 20)
navigationItem.titleView = titleView

iOS 10 及之前的系统 titleView 是直接加在 navigationBar 上面,设定的宽度可以完美的居中显示。而在 iOS 11 的系统上 titleView 是加在 UITAMICAdaptorView 类上。造成 titleView 水平位置有偏移的原因:
UITAMICAdaptorView 是有左右边距限定的

  • 在4.7英寸及以下的屏幕边距是 8p
  • 5.5英寸的屏幕边距 12p
let titleView = BKTitleView.init(frame: ccr(0, 0, kScreenWidth - 30, 30))
if #available(iOS 11.0, *) {
  titleView.center = ccp(kScreenWidth * 0.5 - (DeviceInfo.is4_7Inch == true ? 12 : 8), 20)
} else {
  titleView.center = ccp(kScreenWidth * 0.5, 20)
}
navigationItem.titleView = titleView

2. WKWebView

是 一处 WKWebViewcrash

Completion handler passed to -[XXXXX.BKWebViewController webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once

decisionHandler() 方法调用多次引起的crash,要解决这个crash很简单只需要在执行 decisionHandler() 之后确保不再调用它。

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
   if XXXX {
      //...
      decisionHandler(.cancel)      
   } else {
       //....
      decisionHandler(.allow)
   }
   //...
   decisionHandler(.allow)
}

修复后:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
   if XXXX {
      //...
      decisionHandler(.cancel); return
   } else {
        //....
      decisionHandler(.allow); return
   }
   //...
   decisionHandler(.allow)
}

3. UITableView

iOS 8中我们可以通过实现 estimatedRowHeight 相关属性来展示动态内容,实现了 estimatedRowHeight 的属性后,得到 contentSize 的初始估算值。UITableView 在滑动的过程中会不断的更新cell会重新计算 contentSize ,在滑到最后的时候,得到真正的 contentSize, 期间 contentOffset 也会不断的变化。

    @available(iOS 7.0, *)
    open var estimatedRowHeight: CGFloat // default is UITableViewAutomaticDimension, set to 0 to disable

iOS 11上属性值默认值 estimatedRowHeight 由之前的 0 改为了 UITableViewAutomaticDimension ,这样在 UITableViewHeader、Footer、 UITableViewCell 都是默认使用 estimatedRowHeight。属性默认值 UITableViewAutomaticDimension 这样就造成了contentSizecontentOffset 的变化。在 tableView.reloadDatatableViewoffset 也随着发生了变化。很直观的感觉就是 tableVIew 滑动加载更多之后,当前 offset 发生了偏移给人造成错位的感觉。

iOS 11tableView 头部有额外的间隙。在 iOS 11之前 navigationController 会传入一个 contentInset 给其最顶层的 UIViewControllerscrollView 。以前会设置 UIViewController 中的automaticallyAdjustsScrollViewInsets。 而在 iOS 11 这一行为被改变了,该属性值也被废弃了,而是通过一个新增的属性 adjustedContentInset 来表达。在 iOS11 中, adjustedContentInset 是只读,通过contentInsetAdjustmentBehavior 属性用来配置。UIViewControllerautomaticallyAdjustsScrollViewInsets 属性已经被废弃了。

@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES

@available(iOS 11.0, *)
open var adjustedContentInset: UIEdgeInsets { get }
    
/* Configure the behavior of adjustedContentInset.
Default is UIScrollViewContentInsetAdjustmentAutomatic.
*/
@available(iOS 11.0, *)
open var contentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentBehavior
    

综上所述: 结合实际项目情况 UITableView 要做的适配 :

override func viewDidLoad() {
   super.viewDidLoad()
   
   edgesForExtendedLayout = UIRectEdge()
   extendedLayoutIncludesOpaqueBars = false
   
   if #available(iOS 11.0, *) {
       tableView.contentInsetAdjustmentBehavior = .never
       tableView.estimatedRowHeight = 0
       tableView.estimatedSectionFooterHeight = 0
       tableView.estimatedSectionHeaderHeight = 0
    } else {
        automaticallyAdjustsScrollViewInsets = false
    }
}

4. 图片的权限

iOS 11 系统之前,我们需要访问系统的图片,需要在 info.plist 添加权限说明

/// 图片读写权限
Privacy - Photo Library Usage Description

iOS 11 苹果将图片的读写权限分开,新增了写入 photo album 的权限。如果App需要儲存照片,而且又要兼容 iOS 11 之前的版本。需要在 info.plist 中增加权限,缺一不可。

/// 读
Privacy - Photo Library Usage Description
/// 写
Privacy - Photo Library Additions Usage Description

你可能感兴趣的:(iOS 11 适配)