###### 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