iOS開(kāi)發(fā)之適配的相關(guān)屬性

相關(guān)屬性標(biāo)簽:edgesForExtendedLayout,safeAreaInsets,translucent,automaticallyAdjustsScrollViewInsets,contentInset,adjustedContentInset,contentInsetAdjustmentBehavior

參考鏈接:

1.關(guān)于edgesForExtendedLayout 與 safeAreaInsets

1.1 edgesForExtendedLayout:iOS7推出,指定邊緣要延伸的方向,UIViewController屬性
默認(rèn)UIRectEdgeAll即self.view全屏顯示。
1.2 safeAreaInsets:iOS11推出,安全區(qū)域,view屬性
readonly只讀屬性,系統(tǒng)控制;同時(shí)新增兩個(gè)方法獲取安全區(qū)域改變

UIViewController中新增:
- (void)viewSafeAreaInsetsDidChange;
UIView中新增:
- (void)viewSafeAreaInsetsDidChange;

1.3 以下分別測(cè)試控制器view的frame,view的safeAreaInsets

iOS12.1下測(cè)試,以iPhone X(真機(jī),{375,812})為例

edgesForExtendedLayout view.frame(CGRect) view.safeAreaInsets(UIEdgeInsets)
UIRectEdgeNone (帶導(dǎo)航欄) {{0, 88}, {375, 724}} {0, 0, 34, 0}
UIRectEdgeAll(帶導(dǎo)航欄) {{0, 0}, {375, 812}} {88, 0, 34, 0}
UIRectEdgeNone (不帶導(dǎo)航欄) {{0, 0}, {375, 812}} {44, 0, 34, 0}
UIRectEdgeAll(不帶導(dǎo)航欄) {{0, 0}, {375, 812}} {44, 0, 34, 0}

iOS8.1和12.1下測(cè)試,以iPhone6(模擬器,{375,667})為例

edgesForExtendedLayout view.frame(CGRect) view.safeAreaInsets(UIEdgeInsets) iOS8.1 view.safeAreaInsets(UIEdgeInsets) iOS12.1
UIRectEdgeNone (帶導(dǎo)航欄) {{0, 64}, {375, 603}} 沒(méi)有該屬性 {0, 0, 0, 0}
UIRectEdgeAll(帶導(dǎo)航欄) {{0, 0}, {375, 667}} 沒(méi)有該屬性 {64, 0, 0, 0}
UIRectEdgeNone (不帶導(dǎo)航欄) {{0, 0}, {375, 667}} 沒(méi)有該屬性 {20, 0, 0, 0}
UIRectEdgeAll(不帶導(dǎo)航欄) {{0, 0}, {375, 667}} 沒(méi)有該屬性 {20, 0, 0, 0}

edgesForExtendedLayout值為其他情況時(shí)相信你已經(jīng)知道了,有興趣請(qǐng)自行測(cè)試。

總結(jié):edgesForExtendedLayout屬性影響在是否有NavigationBar,Tabbar時(shí)view的frame;safeAreaInsets屬性影響view的可視范圍的frame。

2.translucent:iOS3推出,半透明度,UINavigationBar屬性

Default is NO on iOS 6 and earlier. Always YES if barStyle is set to UIBarStyleBlackTranslucent
現(xiàn)在的App基本都支持iOS8.0以上,translucent可以認(rèn)為默認(rèn)為YES。translucent為YES,控制器view從坐標(biāo)(0,0)開(kāi)始;translucent為NO,控制器view從(0,64)開(kāi)始。當(dāng)我們使用滾動(dòng)視圖的時(shí)候,比如tableVIew,scrollview時(shí)候,建議不要修改translucent屬性,就是用系統(tǒng)默認(rèn)的YES

edgesForExtendedLayout = UIRectEdgeAll 時(shí)
iOS12.1下測(cè)試,以iPhone X(真機(jī),{375,812})為例

view.frame(CGRect) view.safeAreaInsets(UIEdgeInsets)
translucent = NO (帶導(dǎo)航欄) {{0, 88}, {375, 724}} {0, 0, 34, 0}
translucent = YES (帶導(dǎo)航欄) {{0, 0}, {375, 812}} {88, 0, 34, 0}
translucent = NO(不帶導(dǎo)航欄) {{0, 0}, {375, 812}} {44, 0, 34, 0}
translucent = YES(不帶導(dǎo)航欄) {{0, 0}, {375, 812}} {44, 0, 34, 0}

總結(jié):translucent = NO 與 edgesForExtendedLayout = UIRectEdgeNone效果相同。開(kāi)發(fā)中建議translucent = YES使用默認(rèn)值,在基類(lèi)中修改edgesForExtendedLayout = UIRectEdgeNone來(lái)控制所有控制器View的布局。

3.UIScrollView及其子類(lèi)

首先,根據(jù)以上的默認(rèn)屬性提出一個(gè)問(wèn)題:新建一個(gè)工程,讓初始的控制器(ViewController)帶導(dǎo)航欄,在ViewController的view上添加一個(gè)webview,webview的frame設(shè)置為self.view.frame。請(qǐng)問(wèn)webview的內(nèi)容會(huì)不會(huì)被導(dǎo)航欄擋???代碼理解如下:
有導(dǎo)航欄,translucent = YES 與 edgesForExtendedLayout = UIRectEdgeAll


- (void)viewDidLoad {
    [super viewDidLoad];

    WKWebView *webview = [[WKWebView alloc] init];
    webview.frame = self.view.frame;
    
    [self.view addSubview:webview];
    
    [webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
}

接下來(lái)我們解決了解UIScrollView相關(guān)屬性
automaticallyAdjustsScrollViewInsets: 默認(rèn)YES,自動(dòng)適應(yīng)滾動(dòng)視圖的內(nèi)邊距,在iOS11系統(tǒng)后,該屬性無(wú)效。
scrollView.contentInset: 決定滾動(dòng)視圖的內(nèi)容和邊緣距離的屬性,iOS11由adjustedContentInset決定
adjustedContentInset: iOS11推出,readonly,When contentInsetAdjustmentBehavior allows, UIScrollView may incorporate its safeAreaInsets into the adjustedContentInset.(當(dāng)contentInsetAdjustmentBehavior允許時(shí),UIScrollView可以合并它的safeareainset進(jìn)入adjustedContentInset。)
contentInsetAdjustmentBehavior:內(nèi)邊距適應(yīng)行為,該值決定adjustedContentInset的值。

官方文檔:

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
    UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but for backward compatibility will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewInsets = YES inside a navigation controller, regardless of whether the scroll view is scrollable
    UIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)
    UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjusted
    UIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets
} API_AVAILABLE(ios(11.0),tvos(11.0));

上述問(wèn)題的代碼在iPhone X,iOS12.1下測(cè)試
contentInsetAdjustmentBehavior 以下采用簡(jiǎn)寫(xiě):

AdjustmentAutomatic AdjustmentScrollableAxes AdjustmentNever AdjustmentAlways
automaticallyAdjustsScrollViewInsets YES YES YES YES
contentInsetAdjustmentBehavior 3 1 2 3
scrollView.contentInset {{0, 0}, {0, 0}} {{0, 0}, {0, 0}} {{0, 0}, {0, 0}} {{0, 0}, {0, 0}}
self.view.safeAreaInsets {88, 0, 34, 0} {88, 0, 34, 0} {88, 0, 34, 0} {88, 0, 34, 0}
scrollView.adjustedContentInset {88, 0, 34, 0} {88, 0, 34, 0} {0, 0, 0, 0} {88, 0, 34, 0}

測(cè)試打印:

po self.automaticallyAdjustsScrollViewInsets
po self.webview.scrollView.contentInsetAdjustmentBehavior
po NSStringFromUIEdgeInsets(self.webview.scrollView.contentInset)
po NSStringFromUIEdgeInsets(self.view.safeAreaInsets)
po NSStringFromUIEdgeInsets(self.webview.scrollView.adjustedContentInset)

總結(jié):UIScrollViewContentInsetAdjustmentAutomatic回去選擇一個(gè)最適合的適應(yīng)行為。UIScrollViewContentInsetAdjustmentNever就是adjustedContentInset = contentInsets;
UIScrollViewContentInsetAdjustmentAlways就是adjustedContentInset = safeAreaInsets + contentInsets;
UIScrollViewContentInsetAdjustmentScrollableAxes:它的成立依賴(lài)于滾動(dòng)軸,當(dāng)垂直方向上的contentSize大于滾動(dòng)視圖的高度時(shí),那么垂直方向上的 insets 就由`safeAreaInsets + contentInsets決定,水平方向上同理。

iOS開(kāi)發(fā)之適配的相關(guān)屬性

//豎屏狀態(tài)欄高度
#define Portrait_Status_SafeArea_Height (kDeviceInfo.isiPhoneXSeries ? 44 : 20)
//豎屏底部不帶tabbar安全區(qū)域高度
#define Portrait_Bottom_SafeArea_Height (kDeviceInfo.isiPhoneXSeries ? 34 : 0)
//豎屏底部帶tabbar時(shí)安全區(qū)域高度
#define Portrait_Tabbar_SafeArea_Height (kDeviceInfo.isiPhoneXSeries ? (49 + 34) : 49)
//橫屏底部安全區(qū)域的高度
#define Landscal_Bottom_SafeArea_Height (kDeviceInfo.isiPhoneXSeries ? 21 : 0)
//橫屏左右安全區(qū)域的寬度
#define Landscal_LeftRight_SafeArea_Width (kDeviceInfo.isiPhoneXSeries ? 44 : 49)

現(xiàn)在來(lái)回答最初提出的那個(gè)問(wèn)題:我們添加webview時(shí),使用的frame是self.view.frame,automaticallyAdjustsScrollViewInsets為默認(rèn)YES,在iOS12.1下測(cè)試,所以該屬性無(wú)效,contentInsetAdjustmentBehavior行為未設(shè)置,則默認(rèn)為Automatic即UIScrollViewContentInsetAdjustmentAlways,所以該webview的scrollView.adjustedContentInset為{88, 0, 34, 0},所以?xún)?nèi)容顯示是從導(dǎo)航欄底部開(kāi)始顯示的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容