UINavigationController的导航栏的遮挡和透明

UINavigationController的导航栏的遮挡和透明

1.view被遮挡,默认被装入UINavigationController的子ViewController的view是全屏的,那么会导致子ViewController的view的上部会被UINavigationController的navigation bar 挡住。
2.UINavigationController的navigation bar的透明设置。

@interface BBViewController ()
@property (strong, nonatomic) UIView *subview;
@end

@implementation BBViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    v.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:v];
    
    self.subview = v;
}
@end
BBViewController *bv = [BBViewController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:bv];
nav.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:nav animated:true completion:nil];

尝试解决遮挡问题:(在BBViewController中)
1.改变view的起点,使 view的起点在导航栏底部,不会被挡住。
方法一:
// 但是系统提供一个默认的背景色,使得半透明导航栏有适合的外观

self.edgesForExtendedLayout = UIRectEdgeNone;

// 一般不要使用
// 使用安全区域来代替,以确定界面的那些部分被其他内容挡住, safeAreaLayoutGuide, safeAreaInsets

方法二:
// 导航栏是白色

self.navigationController.navigationBar.translucent = NO;

此属性会被extendedLayoutIncludesOpaqueBars属性影响,如果extendedLayoutIncludesOpaqueBars的属性被设置为YES,则view的起点仍然是屏幕的起点,此属性默认是NO。

2.使用布局来限制子view的位置
方法一:使用NSLayoutConstraint和UILayoutGuide

    v.translatesAutoresizingMaskIntoConstraints = NO;
    UILayoutGuide *guide = self.view.safeAreaLayoutGuide;
    [[v.topAnchor constraintEqualToAnchor:guide.topAnchor] setActive:YES];
    [[v.leftAnchor constraintEqualToAnchor:guide.leftAnchor] setActive:YES];
    [v addConstraint:[NSLayoutConstraint constraintWithItem:v attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant:200]];
    [v addConstraint:[NSLayoutConstraint constraintWithItem:v attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:40]];

方法二: 使用safeAreaInsets

    - (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    // 由于UIView的safeAreaInsets只有在添加到视图层级后才生效,所以把布局代码写下viewDidLayoutSubviews方法中
    UIEdgeInsets inset = self.view.safeAreaInsets;
    CGFloat top = inset.top;
    self.subview.frame = CGRectMake(0, top, 200, 40);
}

此方法会被ViewController的属性additionalSafeAreaInsets影响。
比如:

// 这个会将安全区域下移100
self.additionalSafeAreaInsets = UIEdgeInsetsMake(100, 0, 0, 0);

关于UINavigationController的navigation bar的透明
方法一:使用透明背景图,不推荐。
// 透明但是会残留一条线,view的起点是屏幕的起点

[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];

方法二:使用隐藏,view的起点是屏幕的起点。

    // 隐藏导航栏,对于view来说,就好像没有嵌入navigation controller栈中一样,edgesForExtendedLayout这个属性也无用
    [self.navigationController.navigationBar setHidden:YES];

补充UI层次
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值