iOS11、iPhone X、Xcode9遇到的一些問題




適配iPhone X雖然沒什么難度但是很繁瑣,因?yàn)閷?dǎo)航欄高度一變基本上就影響到了所有頁面。

如果項(xiàng)目是用的自動(dòng)布局,適配起來應(yīng)該會(huì)很快,但是很遺憾我這個(gè)項(xiàng)目沒有使用自動(dòng)布局。

曾經(jīng)偷的懶在iPhone X出現(xiàn)的這天一一償還。

之所以覺得適配繁瑣的原因就是:界面搭建寫死了。

比如說導(dǎo)航欄,項(xiàng)目中的導(dǎo)航欄都是自定義view,初始化的時(shí)候基本是這樣的:

1

2self.naviView?=?[[CQShopCartNaviView?alloc]

initWithFrame:CGRectMake(0,0,?screenWidth,64)];

沒有使用自動(dòng)布局就算了還把高度寫死了。。。

類似的還有tabBar,高度寫死的49,不過整個(gè)項(xiàng)目也就一個(gè)tabBar,所以修改也很快。

適配iPhone X說白了就是修改控件的高度。。。


這次適配iPhone X我的一點(diǎn)經(jīng)驗(yàn)教訓(xùn)就是:


1.一定要合理運(yùn)用自動(dòng)布局

自動(dòng)布局的特點(diǎn)是:它是活的,能夠根據(jù)結(jié)構(gòu)的變化而變化。

相對(duì)于frame絕對(duì)布局,自動(dòng)布局的優(yōu)勢(shì)還是很明顯的,不只是這次適配iPhone X,之前適配熱點(diǎn)被接入時(shí)狀態(tài)欄高度發(fā)生改變我就深有體會(huì)了,如果用的自動(dòng)布局,根本不需要適配,因?yàn)楸緛砭褪莿?dòng)態(tài)變化的,如果是絕對(duì)布局,你要接收狀態(tài)欄高度改變的通知,然后一個(gè)一個(gè)頁面調(diào)整。。。

還有,我迭代開發(fā)一年多的體會(huì)是:自動(dòng)布局面對(duì)多變的需求能更好應(yīng)對(duì)。

2. 通用全局常量一定要用宏定義

這樣可以一處修改,全部修改。

說白了就是不要寫死,比如說導(dǎo)航欄高度,直接寫64直接洗白。

適配iPhone X用到的宏有:

//?判斷是否是iPhone?X

#define?iPhoneX?([UIScreen?instancesRespondToSelector:@selector(currentMode)]???CGSizeEqualToSize(CGSizeMake(1125,2436),?[[UIScreen?mainScreen]?currentMode].size)?:?NO)

//?狀態(tài)欄高度

#define?STATUS_BAR_HEIGHT?(iPhoneX??44.f?:20.f)

//?導(dǎo)航欄高度

#define?NAVIGATION_BAR_HEIGHT?(iPhoneX??88.f?:64.f)

//?tabBar高度

#define?TAB_BAR_HEIGHT?(iPhoneX???(49.f+34.f)?:49.f)

//?home?indicator

#define?HOME_INDICATOR_HEIGHT?(iPhoneX??34.f?:0.f)



3.最頂部的控件向下靠,最底部的控件向上靠

比如說自定義的導(dǎo)航欄:

導(dǎo)航欄中的控件的約束應(yīng)該以底部為基準(zhǔn)。

再比如說自定義的tabBar:



tabbar中的控件的約束應(yīng)該以頂部為基準(zhǔn)。

這樣設(shè)置約束不管將來導(dǎo)航欄或tabbar的高度怎么變都不虛。

實(shí)際項(xiàng)目中最頂部的不一定的是導(dǎo)航欄,最底部的也不一定是tabbar,不管是什么view,只要我們?cè)O(shè)置的約束都是向中間靠的,將來控件的高度怎么改變都不會(huì)導(dǎo)致布局錯(cuò)亂。



1. 升級(jí)后,發(fā)現(xiàn)某個(gè)擁有tableView的界面錯(cuò)亂,組間距和contentInset錯(cuò)亂,因?yàn)閕OS11中 UIViewController 的 automaticallyAdjustsScrollViewInsets 屬性被廢棄了,因此當(dāng)tableView超出安全區(qū)域時(shí),系統(tǒng)自動(dòng)會(huì)調(diào)整SafeAreaInsets值,進(jìn)而影響adjustedContentInset值

// 有些界面以下使用代理方法來設(shè)置,發(fā)現(xiàn)并沒有生效

19//?有些界面以下使用代理方法來設(shè)置,發(fā)現(xiàn)并沒有生效

-?(CGFloat)tableView:(UITableView?*)tableView?heightForHeaderInSection:(NSInteger)section;

-?(CGFloat)tableView:(UITableView?*)tableView?heightForFooterInSection:(NSInteger)section;

//?這樣的原理是因?yàn)橹爸皇菍?shí)現(xiàn)了高度的代理方法,卻沒有實(shí)現(xiàn)View的代理方法,iOS10及以前這么寫是沒問題的,iOS11開啟了行高估算機(jī)制引起的bug,因此有以下幾種解決方法:

//?解決方法一:添加實(shí)現(xiàn)View的代理方法,只有實(shí)現(xiàn)下面兩個(gè)方法,方法?(CGFloat)tableView:?heightForFooterInSection:?才會(huì)生效

-?(UIView?*)tableView:(UITableView?*)tableView?viewForFooterInSection:(NSInteger)section?{

returnnil;

}

-?(UIView?*)tableView:(UITableView?*)tableView?viewForHeaderInSection:(NSInteger)section?{

returnnil;

}

//?解決方法二:直接使用tableView屬性進(jìn)行設(shè)置,修復(fù)該UI錯(cuò)亂

self.tableView.sectionHeaderHeight?=0;

self.tableView.sectionFooterHeight?=5;

[_optionTableView?setContentInset:UIEdgeInsetsMake(-35,0,0,0)];

//?解決方法三:添加以下代碼關(guān)閉估算行高

self.tableView.estimatedRowHeight?=0;

self.tableView.estimatedSectionHeaderHeight?=0;

self.tableView.estimatedSectionFooterHeight?=0;

總結(jié)

編程,一定要靈活,要稍微考慮長(zhǎng)遠(yuǎn)點(diǎn),我當(dāng)初就是想當(dāng)然的認(rèn)為狀態(tài)欄、導(dǎo)航欄和tabbar這些控件的高度是肯定不會(huì)變的,所以就直接寫死了,導(dǎo)致現(xiàn)在不得不一一修改。

一定要緊跟潮流,如果當(dāng)時(shí)我重構(gòu)的時(shí)候就全部使用自動(dòng)布局現(xiàn)在也不用那么麻煩了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容