cell穿透屏幕不同系統的適配以及safearea相關屬性的分析

前言:

xcode升級到9.0以后,對應的模擬器也升級到了ios11.0,框架中屬性有了一些改變,提出了一些新的概念,但這個概念如果決定到了系統的適配,是必須要搞懂的,因為舊低版本系統中一些屬性的設置已經不適用于最新的系統,比如safeArea,看了別人的文章自己還是沒有徹底搞清楚,不如自己去一點點分析來的透徹,寫的比較詳細,請提出寶貴建議,本菜鳥愿與大家一起進階!

開始:

本文研究的視圖層次結構:控制器view上添加scrollview,scrollview上再添加tableview,最后給view上添加標題欄,最外面還有狀態欄和導航欄,對這個結構因為自己很熟悉了,所以不上圖了

原因:很常用并且很有代表性

發現的問題:xcode升級到9.x以后,要實現tableview中的cell能夠穿越整個屏幕,就要設置一個內邊距,即可滾動區域,三步曲:對加到控制器view上的scrollview,利用控制器屬性automaticallyAdjustsScrollViewInsets取消系統設置的內邊距,設置了tableview的y值為0,讓它占滿整個屏幕,再設置tableview的內邊距值為(64+35,0,49,0),然后在ios11模擬器上運行后發現跟之前的系統不一樣了,第一個cell想對于標題欄多下降了一個64的高度,往上拉,最后一個cell多上了49的內邊距,設置內邊距,ios11只需要(35,0,0,0),這里的35指標題欄的高度

分析:

為什么會出現這個問題呢?

對比分析可知,原先需要手動給tableview多調節64的內邊距,而現在不需要了,系統的某個屬性幫做了,而自己手動設置的contentInset屬性上方35仍然起作用,意思就是說原先tableview的contentInset就可以完全決定內容cell的顯示區域,現在得配合另一個屬性才能夠決定。

當時的困惑:這個屬性一定是系統新增的,它到底是什么?為什么要引入這個屬性?如何做這種系統適配?

測試分析:

準備工作:先在xcode中下載了ios9.3,用于對比,在viewDiaAppear方法中進行打印測試,而不是在viewDidLoad中,因為viewDiaAppear方法調用時,對應的view已經顯示好了,已經判斷出了前方有沒有導航欄和狀態欄,決定它顯示范圍的內邊距屬性已經起了作用,這時打印才會有值

條件控制屬性:contentInsetAdjustmentBehavior和automaticallyAdjustsScrollViewInsets對比,我把這些控制條件的叫做條件控制屬性,能夠獲取值的叫做值屬性,這樣概念比較清晰

automaticallyAdjustsScrollViewInsets是屬于控制器對象的屬性,而contentInsetAdjustmentBehavior是屬于scrollview或者tableview的屬性,ios11廢棄了automaticallyAdjustsScrollViewInsets屬性,用contentInsetAdjustmentBehavior來代替,個人覺得這樣是很好的,誰的事情誰管理,以前,盡管控制器對象把它的屬性設置為NO,就能控制scrollview中的tableview范圍不被壓縮,tableview中的cell也不會被壓縮,但是現在不同了,各管理各的

ios11?

scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever

ios9?

self.automaticallyAdjustsScrollViewInsets = NO

看資料后發現,發現系統給tableview或者scrollview新增兩個屬性adjustedcontentInset,safeAreaInsets

對比測試:tableview添加到scrollview上后

1.先不設置tableview內邊距,在ios11.0上運行,contentInset打印之后上下左右為0,明明cell已經下移了啊,系統已經給tableview中的內容設置了內邊距,按理說它應該是有值的,怎么 會是0,如果在ios9.3中,它絕對不會是0,{64, 0, 49, 0},原先它是能反映出系統的自動調整的,前后一對比,升級到11.0以后,說明這個contentInset屬性已經不再能反映出系統的調整行為了,不能作為代表了,能夠代表系統的可能換了屬性了,換成哪個屬性了呢?是safeAreaInsets還是adjustedContentInset,經過打印測試,結果都為{64, 0, 49, 0},這就奇怪了

2.當給tableview設置contentInset后,self.tableView.contentInset = UIEdgeInsetsMake(35, 0, 49, 0);

再次測試打印,self.tableView.contentInset:{35, 0, 49, 0}

self.tableview.safeAreaInsets:{64, 0, 49, 0}

self.tableview.adjustedcontentInset:{99, 0, 98, 0}

adjustedcontentInset =?contentInset +?safeAreaInsets

說明了什么呢?

說明了safeAreaInsets可能是一個恒定的值,是一個標準值,是根據系統中有無導航欄和tabBar來判斷,它的值是系統給設定的,最終能夠反映tableview中內容下移多少的的只能是adjustedcontentInset屬性,它的屬性值是其余兩個屬性值的相加

那么問題又來了,既然adjustedcontentInset是真正反映內邊距是多少的,那么直接設置這個屬性就可以了啊,那么能不能設置呢?

經過測試是不能的,因為它是一個只讀屬性,這個在它的屬性定義標簽里面也能看到,那么ios11引入這個屬性有何用,只能看不能設置?是的,它只能看不能設置,它的只能利用另外兩個屬性的值相加

繼續研究相對的問題:

safeAreaInsets是safearea安全區域相對于tableview邊緣

contentInset是相對于safeArea安全區域

adjustedcontentInset是相對于tableview邊緣


真正能反映tableview中內容的內邊距是adjustedcontentInset

探討safearea安全區域

ios11為什么要引入safeArea呢?

蘋果專門為了iphoneX設備的劉海和下方的欄而改進的系統,提出了safeArea,目的就是為了無論橫屏還是豎屏,顯示的內容會居中,因為屏幕是不規則的,可以認為系統和設備是兩個相對獨立的概念,卻又彼此聯系,既然設備屏幕是不規則的,這是一個沒法改變的事情,而系統規則是可以靈活定義的,只能改變系統了,為了內容的正常顯示,系統里面的規則必須要向設備妥協,這本身是一個最好的選擇,改變環境不如改變自己,但前提是這個設備不應該違反視覺美學

safearea到底是什么?

它并不是一個對象,可以認為是一個規定的顯示范圍,以前,只要scrollview中的內容前面有導航欄和狀態欄,系統直接動手,馬上把你壓下去,而現在系統直接給你劃分了區域,做了規范,你只能在這個區域顯示

這個安全區域的范圍能否改變呢?哪個屬性才能調整它呢?

可以改變,additionalSafeAreaInsets這個屬性可以調整safeAreaInset的指

總結:

scrollview中的內容下移的距離,由adjustedContentInset決定

adjustedContentInset中的x表示scrollview中的內容左上角相對于scrollview的左上角偏移的距離,計算方式由scrollview條件控制屬性contentInsetAdjustmentBehavior決定,主要討論兩種計算方式:

1.默認情況

UIScrollViewContentInsetAdjustmentAutomatic

公式:adjustedcontentInset =?contentInset +?safeAreaInsets

這種情況下,就要考慮contentInset的取值了

2.手動禁止調整內邊距

UIScrollViewContentInsetAdjustmentNever

這種情況雖然打印安全區域內邊距有值,安全區域依然存在,但是它已經不參與計算了

公式:adjustedContentInset = contentInset

適配:

豎屏情況下,不管是哪種設備,哪種系統,如果想做到很靈活的解決內容顯示不會發生偏移,只有手動話控制才能隨心所欲,始終按自己的想法來,一旦有系統的自動化調節參與進來,就很麻煩,分各種情況考慮,所以把系統的自動調整行為完全禁止掉,自己手動設置contentInset,在scrollview初始化方法和tableview控制器的viewDidLoad中各寫一份不同系統下的適配禁止行為,在tableview控制器viewDidLoad方法中只寫一份contentInset設置,取值都一樣

if(@available(iOS11.0, *)) {

? ? ? ? self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

? ? }else{

? ? ? ? self.automaticallyAdjustsScrollViewInsets = NO;

?? ?}

注意:以前取值用常量,但是現在取值不要用常量,最好還是用宏代替,特別是系統欄的值,用方法獲取系統導航欄,狀態欄的高度,因為iphoneX中狀態欄的高度變為了44,而不是20了,自定義的標題欄高度可以用常量

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容