###### tags: `第14屆IT邦鐵人賽文章`
# 【在 iOS 開發路上的大小事2-Day05】更新到 iOS 15 後踩過的坑
Apple 在去年 9 月正式推出 iOS 15 給一般消費者使用
我也觀望了一段時間 (大概一兩個月?) 才更新上去
(畢竟更新 iOS,Xcode 就要跟著更新,也是有點小麻煩呢~)
那時候也有新專案進來,剛好就把新專案的 App 裝在 iOS 15 的手機上
結果就發現了一些 Trouble~
像是 NavigationBar 的顏色不見了、TableView 的 padding 自己長高了
最近則是還有發現 TableView 在 iOS 15 有加入一個預先讀取的功能
然後也對 App 產生了一些小問題
說了這麼多的前情提要,終於要進入正題了 (笑)
進入正文~
### 踩坑1號:NavigationBar 設定好的顏色離家出走了
原先在 iOS 15 以前的 Code 長的像下面這樣
在 iOS 13、iOS 14 上都是可以正常使用的
```swift
self.navigationController?.navigationBar.barTintColor = #colorLiteral(red: 0.7579411864, green: 0.05860135704, blue: 0.1392720342, alpha: 1)
self.navigationController?.navigationBar.tintColor = #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)]
```
但這樣寫,在 iOS 15 上會讓 NavigationBar 的顏色消失,這是為什麼呢?
原因出在 Apple 在 iOS 13 的時候新增了 **UINavigationBarAppearance** 這個 API
而在 iOS 15 的時候,Apple 改用這個 API 來設定
所以也就導致先前我們使用的方法是不可行的,必須另尋出路
那該如何解決呢?很簡單,用下面的方法就可以了~
```swift
if #available(iOS 15.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = #colorLiteral(red: 0.7579411864, green: 0.05860135704, blue: 0.1392720342, alpha: 1)
self.navigationController?.navigationBar.tintColor = #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)]
self.navigationController?.navigationBar.standardAppearance = appearance
self.navigationController?.navigationBar.scrollEdgeAppearance = self.navigationController?.navigationBar.standardAppearance
} else {
self.navigationController?.navigationBar.barTintColor = #colorLiteral(red: 0.7579411864, green: 0.05860135704, blue: 0.1392720342, alpha: 1)
self.navigationController?.navigationBar.tintColor = #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : #colorLiteral(red: 0.9953911901, green: 0.9881951213, blue: 1, alpha: 1)]
}
```
為了與舊版本的 iOS 系統 (iOS 13、iOS 14) 做相容,所以就用 if 來判斷
```
if #available(iOS 15.0, *) 是判斷裝置的 iOS 系統是否為 iOS 15 (含)以上
是的話,就使用新版的 UINavigationBarAppearance API 來進行設定
不是的話,也就是 else,那就使用原先的方法來進行設定
這樣就可以做到新舊 iOS 系統相容了~(撒花)
```
### 踩坑2號:TableView 你怎麼自己長高了
當更新到 iOS 15 後,可能會發現你的 TableView 怎麼自己長高了~
這是因為 Apple 新增了一個 **sectionHeaderTopPadding** 屬性
這個屬性會讓 section 的 header 上方在增加 22 pixels
所以為了看起來跟以前的一樣,我們可以這樣子做
```swift
// 在單一檔案中的做法
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
} else {
// older system settings
}
```
```swift
// 在 AppDelegate 中的做法
if #available(iOS 15.0, *) {
UITableView.appearance().sectionHeaderTopPadding = 0
} else {
// older system settings
}
```
### 踩坑3號:TableView Cell 你怎麼自己亂跳啦 (齁)
在 TableView Cell 裡有 **accessoryType**、**accessoryView** 這兩個屬性可以設定 Cell 右邊的圖示,像是什麼箭頭、info 的 icon 之類的
![](https://i.imgur.com/ZJLpuAB.png)
▲accessoryView 示意圖 (右邊那個紅色倒三角形)
像是之前選完日期後,明明電子信箱的那個 Cell 就沒有設定 accessoryView,但就自己生出一個 accessoryView 了,莫非是無性生殖?
但在 iOS 14 的裝置上,又沒有這個問題,所以我就覺得是 iOS 15 造成的
查了一下後發現,在 iOS 15 的時候,Apple 新增了 **isPrefetchingEnabled** 屬性 (該屬性預設為 true),以及修改了 TableView 的載入方式,會對 Cell 跟資料進行預先讀取,所以可能會造成資料顯示錯亂的問題
所以就確定是 iOS 15 新增的這個屬性搞的鬼~
那要怎麼解決呢~一樣也很簡單~
```swift
// 在單一檔案中的做法
if #available(iOS 15.0, *) {
tableView.isPrefetchingEnabled = false
} else {
// older system settings
}
```
```swift
// 在 AppDelegate 中的做法
if #available(iOS 15.0, *) {
UITableView.appearance().isPrefetchingEnabled = false
} else {
// older system settings
}
```
另外 iOS 15 也有修改 TabBar 的外觀~
但由於我沒用到 UITabBar,所以這邊就不放了~
## 參考資料
> 1. https://juejin.cn/post/7012558803614826526
> 2. https://juejin.cn/post/6982869705274949669
> 3. https://juejin.cn/post/7025517626654720030
> 4. https://stackoverflow.com/questions/69676109/xcode13-ios15-tableview-cellforrowatindexpath-return-a-different-cell
> 5. https://developer.apple.com/documentation/uikit/uinavigationbarappearance/
> 6. https://developer.apple.com/documentation/technotes/tn3106-customizing-uinavigationbar-appearance/
> 7. https://developer.apple.com/documentation/uikit/uitableview/3801922-isprefetchingenabled