美文网首页
Masonry适配safeArea

Masonry适配safeArea

作者: 文子飞_ | 来源:发表于2021-02-06 14:07 被阅读0次

我这里讲解使用的是Masonry,我假设你对约束有一定的了解。

随着iPhone X的出现,iOS页面的适配似乎也麻烦了起来,我见得最多的就是通过某种手段判断机型或者获取导航栏的高度,然后计算宽高。我不说这种方法好不好,因为它也能解决你目前的问题,但不是我喜欢的方式。

在正式开始之前,我先介绍几个重要的知识:

1.topLayoutGuide和bottomLayoutGuide

image.png

这两个属性属于UIViewController,topLayoutGuide主要就是指导航栏,状态栏;bottomLayoutGuide主要指TabBar(刘海手机上也可指代底部黑条的部分),主要就是为了让你使用约束的时候对顶部和底部有个参考,避免视图上的内容被遮挡。

2.safeAreaLayoutGuide

image.png

这个属性是iOS11才有的,也就是苹果对于刘海屏给出的一种解决方案。它和1中的两个属性作用类似,由于属于UIView类,不受限于UIViewController,所以在灵活性上更强。

从它的名字可以看出来,它是一种安全区域的参考,那么安全区域指哪块呢?如下图:

image.png

从上面的图可以看得出来,安全区域可以保证我们的内容不被遮挡。

3. Masonry中相应的属性

既然我们用Masonry,我们就需要知道与系统中对应的属性是哪些:

// 安全区域对应的属性
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuide NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeading NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTrailing NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeft NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideRight NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideBottom NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideWidth NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideHeight NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideCenterX NS_AVAILABLE_IOS(11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideCenterY NS_AVAILABLE_IOS(11.0);
// 一般参考对应的属性
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide NS_DEPRECATED_IOS(8.0, 11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide NS_DEPRECATED_IOS(8.0, 11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop NS_DEPRECATED_IOS(8.0, 11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom NS_DEPRECATED_IOS(8.0, 11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop NS_DEPRECATED_IOS(8.0, 11.0);
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom NS_DEPRECATED_IOS(8.0, 11.0);

从名字中我们就能很清晰的识别出来

self项目实践——底部safeArea适配

static CGFloat const kbottomButtonViewHeight = 55;
/// 底部按钮
- (void)initBottomButtonView
{
    [self.view addSubview:self.bottomSafeAreaBgView];
    [self.bottomSafeAreaBgView addSubview:self.bottomButtonView];
    [self.bottomSafeAreaBgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.bottomButtonView).offset(-10);
        make.leading.trailing.mas_equalTo(self.view);
        make.bottom.mas_equalTo(self.view);
    }];
    [self.bottomButtonView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.trailing.mas_equalTo(self.bottomSafeAreaBgView);
        make.height.mas_equalTo(kbottomButtonViewHeight);
        if (@available(iOS 11.0, *)) {
            make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom);
            //make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(10);
        } else {
            make.bottom.mas_equalTo(self.view);
        }
    }];
}

4.实战

我们创建一个简单的工程,初始页面是一个带有导航栏的红色视图控制器,如下图所示:

image.png

我们将在这上面创建一个绿色的视图,来具体看一下上面1和2提到的属性怎么去用。

首先我们不使用上面的属性来设置约束,代码如下:

UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_top);
make.height.equalTo(@200);
make.left.right.equalTo(self.view);
}]; 

我们只是简单的设置了子视图和父视图之间的约束,似乎看起来没什么问题,但是当我们运行一下就会发现,不好的事情发生了。

image.png

我们的绿色视图竟然被导航栏遮住了一部分,这不是我们所希望了,因为将来有可能遮住我们的重要信息,也许你想着我们可以修改约束中 make.top.equalTo(self.view.mas_top)make.top.equalTo(self.view.mas_top).offset(88) ,让其偏移88,但是这样的坏处是显而易见的,现在偏移88是没问题的,但运行在没有刘海的手机上又要改为偏移64,假如苹果将来又出个神奇的手机,你是不是又要去判断手机型号,然后偏移某一个值呢?从现在起,放弃这种适配方法吧(除了个别目的)。

我们把代码修改为下面这个样子

UIView *view = [[UIView alloc] init];

view.backgroundColor = [UIColor greenColor];

[self.view addSubview:view];

[view mas_makeConstraints:^(MASConstraintMaker *make) {

    if (@available(iOS 11, *)) {

        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);

    } else {

        make.top.equalTo(self.mas_topLayoutGuide);

    }

    make.height.equalTo(@200);

    make.left.right.equalTo(self.view);

}];

这个代码运行出来的效果如下,这样的效果就是我们想要的,内容不会被导航栏遮挡。注意上面的代码,有一个if语句,我们判断了相应API能否在指定平台获取,而这也是我们适配的关键,因为iPhone X以及之后出来的手机,系统肯定是在iOS11之上的(除了个别越狱的),所以我们适配刘海屏的思路就是判断系统版本就够了。

image.png

我们再来看看底部的适配,先上代码

UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@200);
make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_bottom);
}];

这种运行出来的效果为:

image.png

也许你认为这样没什么不好,你说得对,这样是没什么不好,但是底部大约有32的距离是系统不希望我们使用的,因为怕和系统的手势冲突。所以这里我们也是要用到底部的参考和安全区域的参考

UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@200);
make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom); // 或者make.bottom.equalTo(self.mas_bottomLayoutGuide);
}];

运行出来的效果如下,我们可以看到底部空出来了一段距离,这段距离就是系统不希望我们使用的。

image.png

4.总结

通过上面的例子,我们可以看到 topLayoutGuide和bottomLayoutGuidesafeAreaLayoutGuide 的作用区别不大,但是safeAreaLayoutGuide是在视图类中就可以使用,更加方便了我们去做适配。通过参考安全区域或者之前的顶部布局参考,我们不在需要去判断机型,也能达到页面完美适配的目的。

相关文章

  • Masonry适配safeArea

    我这里讲解使用的是Masonry,我假设你对约束有一定的了解。 随着iPhone X的出现,iOS页面的适配似乎也...

  • iOS 11 safeArea详解 & iphoneX

    iOS 11 safeArea详解 & iphoneX 适配 iOS 11 safeArea详解 & iphone...

  • SafeArea widget

    SafeArea widget是适配手机屏幕---刘海屏,底部虚拟按钮等.

  • 版本适配

    屏幕适配 代码适配 Masonry UIView+AutoLayout 可视化适配 autoLayout 系统适配...

  • iPhoneX SafeArea - 安全区域

    iPhoneX SafeArea - 安全区域 一. 前言 本文的出发点是对iOS设备的适配,...

  • Masonry

    Masonry适配 常用属性含义(View+MASShorthandAdditions.h) Masonry NS...

  • 适配 iOS11

    适配 iPhone X 的相关内容详见我的另一篇文章关于 SafeArea 和 适配 iPhoneX 前言 又是一...

  • Autolayout、VFL、Masonry

    适配 VFL语言 Masonry 代码实现Autolayout VFL代码 Masonry使用 总结 使用代码实现...

  • 二.字符串添加*****----请求的数据有----

    (1)号码 添加****** (2)数据中存在 (3)适配SDlayout (4)适配Masonry ...

  • iOS Masonry常用方法

    Masonry就是为屏幕适配而生的三方框架. Masonry基础API 更新约束和布局 Masonry示例代码 常...

网友评论

      本文标题:Masonry适配safeArea

      本文链接:https://www.haomeiwen.com/subject/ahcotltx.html