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));

复制代码

若有错误,欢迎指出。 未完待续……

相关文章
相关标签/搜索