edgesForExtendedLayout、contentInsetAdjustmentBehavior等幾個屬性

  • edgesForExtendedLayout

日常咱們開發的界面的大部分時候都是須要導航欄或tabbar的,或者兩個都須要,導航欄的高度在iphoneX出來以前的設備上是64pt(狀態欄20pt,navigationBar的高度爲44pt),tabbar的高度爲49pt(暫先不考慮tabbar和iPhoneX以後的底部安全高度的狀況下),因此大部分時候咱們顯示的內容的高度都是屏幕的高度減去導航欄和(或)tabbar的高度。 edgesForExtendedLayout做爲控制器UIViewController的屬性,能夠設置該控制器的view是否在導航欄或者tabbar的下邊。edgesForExtendedLayout是枚舉類型,上、下、左、右、全沒和全有。ios

@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);
複製代碼

window的根控制器是導航欄,導航欄的根控制器是tabbar,tabbar有兩個控制器。示例代碼以下。安全

- (void)navTabbar
{
    ViewController *vc = [[ViewController alloc]init];
    SecController *sec = [[SecController alloc]init];
    UITabBarController *tab = [[UITabBarController alloc]init];
    //tab.edgesForExtendedLayout = UIRectEdgeNone;
    tab.viewControllers = @[vc,sec];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:tab];
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
}
複製代碼

以上代碼中,tab.edgesForExtendedLayout = UIRectEdgeNone;vc.edgesForExtendedLayout = UIRectEdgeNone;將兩個控制器的edgesForExtendedLayout都設爲全無的時候,即tabVC的view的頂部不被導航欄遮擋,vc的view的底部不被tabbar遮擋,這樣,最終在咱們顯示的界面上,vc.view的frame就是frame = (0 0; 375 554);若是兩個都設爲全有的狀況下,即相應的view位於被其容器控制器下邊。vc.view的frame就是frame = (0 0; 375 667)bash

如圖: 注:綠色的視圖是vc.view.app

在iphone6模擬器上的效果:左邊爲UIRectEdgeAll,右邊爲 UIRectEdgeNone。對應的vc.view的frame分別爲:左邊frame = (0 0; 375 667),右邊frame = (0 0; 375 554)【屏幕高667-64-49】。 iphone

在iphoneX模擬器上的效果:左邊爲 UIRectEdgeNone,右邊爲 UIRectEdgeAll。對應的vc.view的frame分別爲:左邊:frame = (0 0; 375 641)【屏幕高812-88-49-34】;右邊frame = (0 0; 375 812)。
有一點須要注意的是:若是將navigationBar和tabBar的 translucent(半透明)屬性都設置爲NO的話,即使將控制器的edgesForExtendedLayout都設置爲UIRectEdgeAll,最終控制器的view仍是不會在navigationBar和tabBar的下邊。

vc.navigationController.navigationBar.translucent = NO;
vc.tabBarController.tabBar.translucent = NO;
複製代碼

在storyBoard中的設置以下圖: ui

  • contentInsetAdjustmentBehaviorautomaticallyAdjustsScrollViewInsets
/* Configure the behavior of adjustedContentInset.
 Default is UIScrollViewContentInsetAdjustmentAutomatic.
 */
@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0));
複製代碼

contentInsetAdjustmentBehavior是iOS11.0以後的UIScrollView及其子類的 屬性,默認值是UIScrollViewContentInsetAdjustmentAutomatic。是用來設置scrollView在控制器上的適配內邊距。即scrollView的顯示的內容是否被導航欄及tabBar遮擋。automaticallyAdjustsScrollViewInsets(默認是YES)是iOS11以前(如今已經廢棄)的UIViewController的屬性,其做用與contentInsetAdjustmentBehavior類似,設置控制器上的UIScrollView是否被遮擋。atom

如下示例代碼的效果以下邊的截圖spa

//window及根控制器的設置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ViewController *vc = [[ViewController alloc]init];
    SecController *sec = [[SecController alloc]init];
    UITabBarController *tab = [[UITabBarController alloc]init];
    tab.viewControllers = @[vc,sec];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:tab];
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if (@available(iOS 11.0, *)) {
        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
    } else {
        self.automaticallyAdjustsScrollViewInsets =  YES;
    }
}
//tableView的frame的設置
    - (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.tableView.frame = self.view.bounds;
}

複製代碼

(1): iOS 10.0的iphone6的模擬器的效果 code

由上邊的效果圖能夠看出,當設置控制器的 automaticallyAdjustsScrollViewInsets的屬性是YES的時候,tableView的上部不會被遮擋,從控制檯打印結果能夠看出,其 contentInset的top爲64;即頂部留出了64的內邊距。可是下邊依然被tabBar遮擋,從動圖看也是有一行cell被遮蓋了,控制檯的打印結果也顯示下邊沒有內邊距。看來若是想要tableView的下邊不被tabBar遮擋,須要設置控制器的 edgesForExtendedLayout或者設置計算好的tableView的frame。更方便的是用 autolayout

(2): iOS 12.2的iphoneX的模擬器效果cdn

從圖上效果看出,在iOS11.0以後,將tableView的 contentInsetAdjustmentBehavior設置爲 UIScrollViewContentInsetAdjustmentAutomatic後,tabelView的上邊和下邊都不會被遮擋,從控制檯打印看出tableView的frame雖然是屏幕的高度,可是偏移量 contentOffset是-88,並且在iOS11.0以後, UIScrollView增長了一個屬性 adjustedContentInset適配後的內邊距。看打印結果顯示tableView的適配後內邊距上下分別是88和83,從而避免上下被遮擋。

/* When contentInsetAdjustmentBehavior allows, UIScrollView may incorporate
 its safeAreaInsets into the adjustedContentInset.
 */
@property(nonatomic, readonly) UIEdgeInsets adjustedContentInset API_AVAILABLE(ios(11.0),tvos(11.0));

複製代碼

若有錯誤,歡迎指出。 未完待續……

相關文章
相關標籤/搜索