iOS11及xcode9的適配問題

簡單寫一些梢杭、還在摸索中...


1.升級(jí)iOS11后造成的變化

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


// 有些界面以下使用代理方法來設(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 {

return nil;

}

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

return nil;

}

// 解決方法二:直接使用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;

1.2 如果使用了Masonry 進(jìn)行布局峡碉,就要適配safeArea

? ? ? ? ? ?if ([UIDevice currentDevice].systemVersion.floatValue >= 11.0) {

? ? ? ? ?make.edges.equalTo(self.view.safeAreaInsets);

? ? ? ? ? } else {

? ? ? ? ? make.edges.equalTo(self.view);

? ? ? ? }

1.3 對(duì)于IM的發(fā)送原圖功能,iOS11啟動(dòng)全新的HEIC 格式的圖片驮审,iPhone7以上設(shè)備+iOS11排出的live照片是".heic"格式圖片鲫寄,同一張live格式的圖片吉执,iOS10發(fā)送就沒問題(轉(zhuǎn)成了jpg),iOS11就不行

? ? ? 微信的處理方式是一比一轉(zhuǎn)化成jpg格式

? ? ?QQ和釘釘?shù)奶幚矸绞绞侵苯訅嚎s地来,即使是原圖也壓縮為非原圖

? ? ?微信的逼格太高戳玫,沒找到現(xiàn)成的方法,我采用的是QQ 的方案

2未斑、使用Xcode9 編譯后發(fā)現(xiàn)的問題

? ?2.1 發(fā)現(xiàn)“fastSocket”第三方報(bào)錯(cuò)咕宿,具體原因是缺少C99的頭文件,引入“#include ”即可

?2.2 導(dǎo)航欄的新特性

? ? 原生的搜索欄樣式發(fā)生改變

右邊為iOS11樣式颂碧,搜索區(qū)域高度變大荠列,字體變大

查看 API 后發(fā)現(xiàn),iOS11后將searchController賦值給了NavigationItem载城,通過屬性hidesSearchBarWhenScrolling可以控制搜索欄是否在滑動(dòng)的時(shí)候進(jìn)行隱藏和顯示


// A view controller that will be shown inside of a navigation controller can assign a UISearchController to this property to display the search controller’s search bar in its containing navigation controller’s navigation bar.

@property (nonatomic, retain, nullable) UISearchController *searchController API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);

// If this property is true (the default), the searchController’s search bar will hide as the user scrolls in the top view controller’s scroll view. If false, the search bar will remain visible and pinned underneath the navigation bar.

@property (nonatomic) BOOL hidesSearchBarWhenScrolling API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);

另外肌似,UINavigationBar新增屬性 BOOL值prefersLargeTitles來實(shí)現(xiàn)下面的效果,并可以通過largeTitleTextAttributes來設(shè)置大標(biāo)題的文本樣式诉瓦。設(shè)置大標(biāo)題之后川队,導(dǎo)航欄的高度就會(huì)由之前的64pt變成 96pt,如果項(xiàng)目中有直接寫死的高度或者隱藏導(dǎo)航欄之類的操作睬澡,就需要適配一下

有個(gè)界面使用到了導(dǎo)航欄按鈕相關(guān)的frame固额,也發(fā)生了UI錯(cuò)亂,查看UI層級(jí)關(guān)系后發(fā)現(xiàn)煞聪,iOS11以前是直接把按鈕加到了UINavigationBar上面斗躏,而iOS11則是先將按鈕加到了_UITAMICAdaptorView,再加到_UIButtonBarStackView昔脯、_UINavigationBarContentView治宣,接著才是UINavigationBar矾克。因此如果需要獲取導(dǎo)航欄按鈕 frame 或者 superView,這里需要專門做下適配


3.iPhone X的適配

? ?下載完Xcode9之后,第一件事自然是在 iPhone X(模擬器)上過把癮鹏秋,然后編譯后就發(fā)現(xiàn)報(bào)錯(cuò)了

? ?由于iPhone X的狀態(tài)欄是和其他版本手機(jī)差異比較大的覆旭,因此api 變化也比較大

? ?先后做了以下適配

? 適配點(diǎn)一:項(xiàng)目中使用狀態(tài)欄中圖標(biāo)判斷當(dāng)前網(wǎng)絡(luò)的具體狀態(tài)

出錯(cuò)的代碼

打印的 Log 報(bào)出以下錯(cuò)誤: Trapped uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key foregroundView.'

// 測(cè)試代碼

#import

NSMutableString *resultStr = [NSMutableString string];

//獲取指定類的Ivar列表及Ivar個(gè)數(shù)

unsignedintcount = 0;

Ivar *member = class_copyIvarList([[application valueForKeyPath:@"_statusBar"]class], &count);

for(inti = 0; i < count; i++){

Ivar var = member[i];

//獲取Ivar的名稱

constchar*memberAddress = ivar_getName(var);

//獲取Ivar的類型

constchar*memberType = ivar_getTypeEncoding(var);

NSString *str = [NSString stringWithFormat:@"key = %s?????? type = %s \n",memberAddress,memberType];

[resultStr appendString:str];

}

NSLog(@"%@", resultStr);

iPhone X


其他手機(jī)

使用 runtime 打印其所有屬性蓬网,發(fā)現(xiàn)以下差異

// 測(cè)試代碼

#import

NSMutableString *resultStr = [NSMutableString string];

//獲取指定類的Ivar列表及Ivar個(gè)數(shù)

unsigned int count = 0;

Ivar *member = class_copyIvarList([[application valueForKeyPath:@"_statusBar"] class], &count);

for(int i = 0; i < count; i++){

Ivar var = member[i];

//獲取Ivar的名稱

const char *memberAddress = ivar_getName(var);

//獲取Ivar的類型

const char *memberType = ivar_getTypeEncoding(var);

NSString *str = [NSString stringWithFormat:@"key = %s? ? ? ? ? ? type = %s

\n",memberAddress,memberType];

[resultStr appendString:str];

}

NSLog(@"%@", resultStr);


// 其他版本的手機(jī)

key = _inProcessProvider? ? ? ? ? ? type = @""

key = _backgroundView? ? ? ? ? ? ? type = @"UIStatusBarBackgroundView"

key = _doubleHeightLabel? ? ? ? ? ? type = @"UILabel"

key = _doubleHeightLabelContainer? type = @"UIView"

key = _currentDoubleHeightText? ? ? type = @"NSString"

key = _currentRawData? ? ? ? ? ? ? type = {超長螟碎。。}

key = _interruptedAnimationCompositeViews? type = @"NSMutableArray"

key = _newStyleBackgroundView? ? ? type = @"UIStatusBarBackgroundView"

key = _newStyleForegroundView? ? ? type = @"UIStatusBarForegroundView"

key = _slidingStatusBar? ? ? ? ? ? type = @"UIStatusBar"

key = _styleAttributes? ? ? ? ? ? ? type = @"UIStatusBarStyleAttributes"

key = _waitingOnCallbackAfterChangingStyleOverridesLocally? type = B

key = _suppressGlow? ? ? ? ? ? ? ? type = B

key = _translucentBackgroundAlpha? type = d

key = _showOnlyCenterItems? ? ? ? ? type = B

key = _foregroundViewShouldIgnoreStatusBarDataDuringAnimation? type = B

key = _tintColor? ? ? ? ? ? ? ? ? ? type = @"UIColor"

key = _lastUsedBackgroundColor? ? ? type = @"UIColor"

key = _nextTintTransition? ? ? ? ? type = @"UIStatusBarStyleAnimationParameters"

key = _overrideHeight? ? ? ? ? ? ? type = @"NSNumber"

key = _disableRasterizationReasons? type = @"NSMutableSet"

key = _timeHidden? ? ? ? ? ? ? ? ? type = B

key = _statusBarWindow? ? ? ? ? ? ? type = @"UIStatusBarWindow"

// iPhone X

key = _statusBar ; type = @"_UIStatusBar"

// 因此可見iPhone X的狀態(tài)欄是多嵌套了一層鲸拥,多取一次即可拐格,最終適配代碼為:

NSArray *children;

// 不能用 [[self deviceVersion] isEqualToString:@"iPhone X"] 來判斷,因?yàn)閕Phone X 的模擬器不會(huì)返回 iPhone X

if ([[application valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {

children = [[[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];

} else {

children = [[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];

}

3.2解決這個(gè)問題后項(xiàng)目跑起來發(fā)現(xiàn)刑赶,整個(gè)app界面上下各空出大概40pt的高度

會(huì)發(fā)現(xiàn)底部 UITabBar 是高出一些高度禁荒,查看層級(jí)關(guān)系后發(fā)現(xiàn),同樣是由于安全區(qū)的原因角撞,UITabBar 高度由49pt變成了83pt呛伴,因此這里也要對(duì)iPhone X 及其模擬器進(jìn)行適配

3.3:iPhone X 只有 faceID,沒有touchID谒所,如果in的應(yīng)用有使用到 touchID 解鎖的地方热康,這里要根據(jù)機(jī)型進(jìn)行相應(yīng)的適配

3.4:之前有偷懶的直接使用20替代狀態(tài)欄高度,這些坑都要通過重新獲取狀態(tài)欄高度

? ? ? ?CGRectGetHeight([UIApplication sharedApplication].statusBarFrame)

3.5:然而iPhone X更大的坑是屏幕的適配

首先看下屏幕尺寸

這張圖反映出不少信息:

iPhone X的寬度雖然和7是一樣的劣领,但是高度多出145pt

使用三倍圖是重點(diǎn)姐军,而且一般認(rèn)為肉眼所能所能識(shí)別的最高的屏幕密度是300ppi,iPhone X已達(dá)到458ppi(查證發(fā)現(xiàn)三星galaxy系列的屏幕密度是522ppi)

在設(shè)計(jì)方面尖淘,蘋果官方文檔有明確要求奕锌,下面結(jié)合圖例進(jìn)行說明:

展示出來的設(shè)計(jì)布局要求填滿整個(gè)屏幕
填滿的同時(shí)要注意控件不要被大圓角和傳感器部分所遮擋
安全區(qū)域以外的部分不允許有任何與用戶交互的控件

上面這張圖內(nèi)含信息略多

頭部導(dǎo)航欄不予許進(jìn)行用戶交互的,意味著下面這兩種情況 Apple 官方是不允許的

底部虛擬區(qū)是替代了傳統(tǒng)home鍵村生,高度為34pt惊暴,通過上滑可呼起多任務(wù)管理,考慮到手勢(shì)沖突趁桃,這部分也是不允許有任何可交互的控件辽话,但是設(shè)計(jì)的背景圖要覆蓋到非安全區(qū)域

狀態(tài)欄在非安全區(qū)域,文檔中也提到卫病,除非可以通過隱藏狀態(tài)欄給用戶帶來額外的價(jià)值油啤,否則最好把狀態(tài)欄還給用戶

重復(fù)使用現(xiàn)有圖片時(shí),注意長寬比差異蟀苛。iPhone X 與常規(guī) iPhone 的屏幕長寬比不同益咬,因此,全屏的 4.7 寸屏圖像在 iPhone X 上會(huì)出現(xiàn)裁切或適配寬度顯示帜平。所以幽告,這部分的視圖需要根據(jù)設(shè)備做出適配。

注意類似占位圖的適配

3.6:設(shè)備信息

if ([deviceString isEqualToString:@"iPhone10,1"])? return @"iPhone 8";

if ([deviceString isEqualToString:@"iPhone10,4"])? return @"iPhone 8";

if ([deviceString isEqualToString:@"iPhone10,2"])? return @"iPhone 8 Plus";

if ([deviceString isEqualToString:@"iPhone10,5"])? return @"iPhone 8 Plus";

if ([deviceString isEqualToString:@"iPhone10,3"])? return @"iPhone X";

if ([deviceString isEqualToString:@"iPhone10,6"])? return @"iPhone X";

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末罕模,一起剝皮案震驚了整個(gè)濱河市评腺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淑掌,老刑警劉巖蒿讥,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抛腕,居然都是意外死亡芋绸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門担敌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摔敛,“玉大人,你說我怎么就攤上這事全封÷黻迹” “怎么了桃犬?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長行楞。 經(jīng)常有香客問我攒暇,道長,這世上最難降的妖魔是什么子房? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任形用,我火速辦了婚禮,結(jié)果婚禮上证杭,老公的妹妹穿的比我還像新娘田度。我一直安慰自己,他們只是感情好解愤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布镇饺。 她就那樣靜靜地躺著,像睡著了一般琢歇。 火紅的嫁衣襯著肌膚如雪兰怠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天李茫,我揣著相機(jī)與錄音揭保,去河邊找鬼。 笑死魄宏,一個(gè)胖子當(dāng)著我的面吹牛秸侣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宠互,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼味榛,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了予跌?” 一聲冷哼從身側(cè)響起搏色,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎券册,沒想到半個(gè)月后频轿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烁焙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年航邢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骄蝇。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡膳殷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出九火,到底是詐尸還是另有隱情赚窃,我是刑警寧澤册招,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站考榨,受9級(jí)特大地震影響跨细,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜河质,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望震叙。 院中可真熱鬧掀鹅,春花似錦、人聲如沸媒楼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽划址。三九已至扔嵌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夺颤,已是汗流浹背痢缎。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留世澜,地道東北人独旷。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像寥裂,于是被迫代替她去往敵國和親嵌洼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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