App 适配 iOS11 和 iPhone X

November 10, 2017

1.iOS 11 UINavigationItem.backBarItem 隐藏 “返回” 文字

iOS 11之前是通过

1
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: CGFloat.greatestFiniteMagnitude , vertical: 0), for: .default) 

方法使 “返回” 文字隐藏的。但是在 iOS 11 中就不行了,而且导致 navigationbar 的 title 没见了,通过 debug 发现是因为设置了 CGFloat.greatestFiniteMagnitude 同时把 title 挤走了。

解决方案:

1
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: -CGFloat.greatestFiniteMagnitude , vertical: 0), for: .default) 

2.iOS 11 UIBarButtonItem.width = -7 无效

http://blog.csdn.net/guo4114/article/details/78053025

采用 UIBarButtonItem(CustomView: Btn) 方式

3.iOS 11 UIScrollView contentInset 问题,替换成了 contentInsetAdjustmentBehavior

4.iOS 11 WKWebView contentInset 问题

https://stackoverflow.com/questions/45662388/ios-11-uiwebview-pop-down-by-status-bar

采用 更改 frame 这种方式

5.iOS 11 自定义 Navigationbar 高度、透明度问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import UIKit

class YYNavigationBar: UINavigationBar {

    // 更改 YYNavigationBar 背景 透明度
    var backgroundAlpha: CGFloat? {
        didSet {
            if let alpha = backgroundAlpha {
                if #available(iOS 11.0, *) {
                    self.subviews.forEach { (subview) in
                        if NSStringFromClass(type(of: subview)).contains("BarBackground") {
                            subview.alpha = alpha
                        }
                    }
                } else {
                    self.subviews.first?.alpha = alpha
                }
            }
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        if #available(iOS 11.0, *) {
            self.subviews.forEach { (subview) in
                if NSStringFromClass(type(of: subview)).contains("BarBackground") {
                    subview.y = 0
                    subview.height = Constants.Layout.navBarHeight
                }
                if NSStringFromClass(type(of: subview)).contains("BarContentView") {
                    subview.y = Constants.Layout.statusBarHeight
                    subview.height = Constants.Layout.navBarHeight - Constants.Layout.statusBarHeight
                }
            }
        }
        
        if let alpha = backgroundAlpha {
            if #available(iOS 11.0, *) {
                self.subviews.forEach { (subview) in
                    if NSStringFromClass(type(of: subview)).contains("BarBackground") {
                        subview.alpha = alpha
                    }
                }
            } else {
                self.subviews.first?.alpha = alpha
            }
        }
        
    }

}

6.iOS11 UITableView 取消自动算高

1
2
3
4
5
if #available(iOS 11.0, *) {
    tableView.estimatedRowHeight = 0
    tableView.estimatedSectionHeaderHeight = 0
    tableView.estimatedSectionFooterHeight = 0
}

7.Swift 4内存访问安全

Simultaneous accesses to 0x10580, but modification requires exclusive access

http://www.jianshu.com/p/29d4c4b7ee88

8.**UITableView Refresher 的 KVO 问题

可以参考 PullToRefresh 的 “Swift 4 and kvo” merge

9.适配 iPhone X 的一些变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
static var navBarY: CGFloat {
      switch UIDevice.current.kind {
      case .iPhoneX:
          return 20
      default:
          return 0
      }
  }
        
static var navBarHeight: CGFloat {
    switch UIDevice.current.kind {
    case .iPhoneX:
        return 88
    default:
        return 64
    }
}

static var tabBarHeight: CGFloat {
    switch UIDevice.current.kind {
    case .iPhoneX:
        return 83
    default:
        return 49
    }
}

static var statusBarHeight: CGFloat {
    switch UIDevice.current.kind {
    case .iPhoneX:
        return 44
    default:
        return 20
    }
}

static var adjustInsetForIPhoneX: UIEdgeInsets {
    switch UIDevice.current.kind {
    case .iPhoneX:
        return UIEdgeInsets(top: 0, left: 0, bottom: 34, right: 0)
    default:
        return UIEdgeInsets.zero
    }
}

参考资料

  1. Updating Your App for iOS 11

  2. 你可能需要为你的APP适配iOS11

  3. iPhone X 人机交互界面指南

  4. 关于刘海打理这种事儿,美团点评的iOS工程师早就有经验了,不信你看!