升級xCode9 導航欄變化及一些小技巧
導航欄
導航欄高度的變化
iOS11之前導航欄預設高度為64pt(這裡高度指statusBar + NavigationBar),iOS11之後如果設定了prefersLargeTitles = YES則為96pt,預設情況下還是64pt,但在iPhoneX上由於劉海的出現statusBar由以前的20pt變成了44pt,所以iPhoneX上高度變為88pt,如果專案裡隱藏了導航欄加了自定義按鈕之類的,這裡需要注意適配一下。
導航欄圖層及對titleView佈局的影響
iOS11之前導航欄的title是新增在UINavigationItemView上面,而navigationBarButton則直接新增在UINavigationBar上面,如果設定了titleView,則titleView也是直接新增在UINavigationBar上面。iOS11之後,大概因為largeTitle的原因,檢視層級發生了變化,如果沒有給titleView賦值,則titleView會直接新增在_UINavigationBarContentView上面,如果賦值了titleView,則會把titleView新增在_UITAMICAdaptorView上,而navigationBarButton被加在了_UIButtonBarStackView上,然後他們都被加在了_UINavigationBarContentView上,如圖:
所以如果你的專案是自定義的navigationBar,那麼在iOS11上執行就可能出現佈局錯亂的bug,解決辦法是重寫UINavigationBar的layoutSubviews方法,調整佈局,上程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- ( void )layoutSubviews { [ super layoutSubviews]; //注意導航欄及狀態列高度適配 self.frame = CGRectMake( 0 , 0 , CGRectGetWidth(self.frame), naviBarHeight); for (UIView *view in self.subviews) { if ([NSStringFromClass([view class ]) containsString:@ "Background" ]) { view.frame = self.bounds; } else if ([NSStringFromClass([view class ]) containsString:@ "ContentView" ]) { CGRect frame = view.frame; frame.origin.y = statusBarHeight; frame.size.height = self.bounds.size.height - frame.origin.y; view.frame = frame; } } } |
再補充一點,看了簡書App適配iOS11發現titleView支援autolayout,這要求titleView必須是能夠自撐開的或實現了- intrinsicContentSize方法
1
2
3
|
- (CGSize)intrinsicContentSize { return UILayoutFittingExpandedSize; } |
UIScrollView、UITableView、UICollectionView
大家在iOS11裝置上執行出現最多問題應該就是tableview莫名奇妙的偏移20pt或者64pt了。。原因是iOS11棄用了automaticallyAdjustsScrollViewInsets屬性,取而代之的是UIScrollView新增了contentInsetAdjustmentBehavior屬性,這一切的罪魁禍首都是新引入的safeArea,關於safeArea適配這篇文章iOS 11 安全區域適配總結講的很詳細,感興趣的可以看下,我直接貼適配程式碼,因為低版本直接用contentInsetAdjustmentBehavior會報警告,所有定義瞭如下的巨集(感謝@炒雞範的指正,之前的巨集犯了個低階錯誤...現改為)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#define adjustsScrollViewInsets(scrollView)\ do {\ _Pragma( "clang diagnostic push" )\ _Pragma( "clang diagnostic ignored \"-Warc-performSelector-leaks\"" )\ if ([scrollView respondsToSelector:NSSelectorFromString(@ "setContentInsetAdjustmentBehavior:" )]) {\ NSMethodSignature *signature = [UIScrollView instanceMethodSignatureForSelector:@selector(setContentInsetAdjustmentBehavior:)];\ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\ NSInteger argument = 2 ;\ invocation.target = scrollView;\ invocation.selector = @selector(setContentInsetAdjustmentBehavior:);\ [invocation setArgument:&argument atIndex: 2 ];\ [invocation retainArguments];\ [invocation invoke];\ }\ _Pragma( "clang diagnostic pop" )\ } while ( 0 ) |
還有的發現某些介面tableView的sectionHeader、sectionFooter高度與設定不符的問題,在iOS11中如果不實現 -tableView: viewForHeaderInSection:和-tableView: viewForFooterInSection: ,則-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會被呼叫,導致它們都變成了預設高度,這是因為tableView在iOS11預設使用Self-Sizing,tableView的estimatedRowHeight、estimatedSectionHeaderHeight、 estimatedSectionFooterHeight三個高度估算屬性由預設的0變成了UITableViewAutomaticDimension,解決辦法簡單粗暴,就是實現對應方法或把這三個屬性設為0。
如果你使用了Masonry,那麼你需要適配safeArea
1
2
3
4
5
|
if (@available(iOS 11.0 , *)) { make.edges.equalTo()(self.view.safeAreaInsets) } else { make.edges.equalTo()(self.view) } |
iPhoneX
LaunchImage
關於iPhoneX(我就不吐槽劉海了...),如果你的APP在iPhoneX上執行發現沒有充滿螢幕,上下有黑色區域,那麼你應該也像我一樣LaunchImage沒有用storyboard而是用的Assets,解決辦法如圖,啟動圖的尺寸為1125x2436,or you can iOS開發時如何使用 Launch Screen Storyboard。
TabBarController
因為我們的專案用了第三方的TabBarController,在iPhoneX執行,tabBar看起來怪怪的...估計作者要等到猴年馬月才適配iPhoneX,專案又著急上線,就自己修改了第三方,主要是tabBar高度及tabBarItem偏移適配,iPhoneX由於底部安全區的原因UITabBar高度由49pt變成了83pt,可以通過判斷機型來修改相關介面程式碼
1
|
#define kDevice_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake( 1125 , 2436 ), [[UIScreen mainScreen] currentMode].size) : NO)
|
1.模擬器的變化
相信很多人不太習慣新版模擬器, 那麼如何恢復呢, 看下圖:是不是切換很隨意.
2.Jump to Definition 點選物件跳轉
在XCode9之前,在變數或方法上, 按CMD+單擊, 是直接Jump to Definition,但是現在, 是彈出這個選單, 對於跳轉到變數的定義,就多了一步了,開始可能會覺得不方便 對於想直接跳轉到變數定義,現在是 control+command+單擊, 也可以:
滑鼠使用者: 對準你的物件,Command+滑鼠右鍵
觸控板使用者: 對準你的物件, Command+雙指點選
如果你有強迫症, 非要找回之前一模一樣的感覺, 我也可以幫你哦:
是不是很爽啊, 找回初戀的感覺!
3.摺疊程式碼
Xcode9之前:
區域性摺疊(摺疊一個函式):Command+Option+Left/Right
全域性摺疊(摺疊當前檔案下的全部函式): Shift+Command+Option+Left/Right
摺疊註釋塊:(/* */之間的文字):Ctrl+Shift+Command+Left/Right現在:Fold,可以用來摺疊方法:
4.程式碼編譯器可以放大/縮小自由切換
你還為每週的團隊程式碼分享因螢幕小看不清程式碼而糾結嗎? 這裡就解決了這個問題!
cmd +/- 可以實現編譯器的放大縮小
5.無線開發真機除錯
目前僅支援ios11的真機,使用較簡單,只需在window->Devices and Simulators 下連真機勾選Connect via network, 需要注意的是,必須在一個區域網下:
6.XCode內建的git系統
Source Control的極大增強
支援Github賬戶, XCode -> Preferences -> Accouts 可以登入你的GitHub賬戶, 登入後如下:
通過Xcode的選單 Source Control 最下方的clone, 就可以clone你的github上的工程了,是不是非常方便呢?
7.模擬器可以多開了,並且,模擬器可以登入
這裡不做過多介紹
8.程式碼重構
對一個方法或者變數的重新命名, 在方法上CMD+單擊, 出現的選單, 選擇rename 可以看到, 它把重新命名會出現的改動,比較直觀哈!
9.Folder和Group的同步問題
在此之前,我們在XCode中,更改Folder的名字,在FInder中工程對應的資料夾的名字並不會同步的改變,這會造成我們重新命名資料夾變得非常不方便,最終要先在XCode中移除,然後在Finder中重新命名,再新增回Xcode
現在 在Xcode9中重名命Folder,Finder中的也同步的改變了 我們之前建議一個虛擬的group,並不會在對應的資料夾中建立真實的目錄
Xcode9中,預設行為改變了, 變成了會建立對應的真實資料夾, 如果你需要像之前那樣只是建立虛擬的group, 選擇New Group without Folder 即可!
Show in Finder 可以看到,建立了真實的資料夾:
你可能你會擔心, 區分不了這個group到底是虛擬的,還是實際的, 蘋果給出了標識來區分的, 虛擬的左下角有個小的三角形, 如圖:
10.意外警告
如果你收到 This block declaration is not a prototype
Insert ‘void’ 這個警告,如何徹底關閉呢?
Build Settings -> Strict Prototypes 設定為NO即可, 這只是個臨時方案.
11.建立新的顏色 asset catalog
通常我們會 New image set, 現在可以 New color set, 然後填充 rgb alpha 值, 具體怎麼操作呢?
Assets.xcassets -> + -> New color set-> 填充RGB及alpha
程式碼呼叫方法:
UIColor *customColor; // colorNamed: iOS11才有的, 要做版本判斷. if (@available(iOS 11, *)) { // customColor是自定義顏色的檔名字. customColor = [UIColor colorNamed:@"customColor"]; } else { customColor = [UIColor colorWithRed:1 green:0.427 blue:1.0 alpha:1.0]; }
在適配時 導航欄高度 通常寫成44 + StatusbarHeight
#define TabbarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20 ? 83 : 49) // 適配iPhone x 底欄高度
#define StatusbarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height) //導航欄高度
相關文章
- iOS 導航欄背景顏色完全透明及漸變iOS
- CSS導航欄及下拉選單CSS
- 常用元件 / 導航欄及圖示元件
- PbootCms導航選單標籤的這些小技巧你都知道嗎?boot
- 前端優化的一些小技巧前端優化
- iOS 超Easy實現 漸變導航欄iOS
- iOS 導航欄顏色透明度漸變iOS
- JS寫的二級導航欄(利用冒泡原理)JS
- WordPresscategory導航欄Go
- qml 導航欄TabBar 工具欄ToolBartabBar
- 簡易的iOS導航欄顏色漸變方案iOS
- 定製化你的ReactNative底部導航欄React
- GitHub 導航欄加強Github
- HTML橫向導航欄HTML
- Flutter 導航欄AppBarFlutterAPP
- Tablayout實現導航欄TabLayout
- iOS 導航欄的控制iOS
- bootstrap導航欄學習boot
- 快速實現底部導航欄及未讀訊息
- jquery的一些小技巧jQuery
- svelte自定義元件|導航條Navbar及選單欄Tabbar元件tabBar
- uniapp自定義導航欄APP
- iOS系統導航欄自定義標題動畫跳變解析iOS動畫
- Django2.0開發-前端導航欄切換activate改變Django前端
- [提問交流]能直接設定二級導航欄目嗎?
- CSS實現的側欄三級導航選單程式碼CSS
- 深入 TypeScript - 3 ( 一些小技巧)TypeScript
- Android Studio 3.0 的一些小變化Android
- Linux系統導航技巧Linux
- Linux 目錄導航技巧Linux
- 在 Flutter 中實現一個浮動導航欄Flutter
- 可以任意定製導航欄背景的一個思路
- 一個簡單易用的 Android 導航欄TitleBarAndroid
- 微信小程式自定義導航欄微信小程式
- ios自定義簡約導航欄iOS
- CSS 導航欄元素居中顯示CSS
- iOS導航欄佈局相關iOS
- 構建動態互動式H5導航欄:滑動高亮、吸頂和錨點導航技巧詳解H5