iOS SafeArea安全区域

1. 前言

本文的出发点是对iOS设备的适配, 我们之前的适配只是考虑设备的尺寸, 设备的方向, 而在iPhoneX出来之后呢, 我们又多了一种考量, 那就是刘海和底部横条(HomeIndicator), 我们通过UIKit11.0之后新增的API来解决这个问题, 达到不同设备尺寸, 不同设备方向的完美适配。

2. 之前的做法

注: 该方法只适用于设备的竖屏, 如果是横屏就会出现问题
我们是用宏, 来解决这个问题的, 像这样:

/** 设备屏幕宽度 */
#define LCLScreenWidth [[UIScreen mainScreen] bounds].size.width

/** 设备屏幕高度 */
#define LCLScreenHeight [[UIScreen mainScreen] bounds].size.height

/** iPhoneX判断 */
#define LCLIsIphoneX (CGSizeEqualToSize(CGSizeMake(375.f, 812.f), UIScreen mainScreen].bounds.size) || CGSizeEqualToSize(CGSizeMake(812.f, 375.f), [UIScreen mainScreen].bounds.size))

/** 状态栏高度 */
#define LCL_StatusBar_Height ((LCLIsIphoneX) ? 44 : 20)

/** 导航栏高度 */
#define LCL_NavBar_Height ((LCLIsIphoneX) ? 88 : 64)

/** 标签栏高度 */
#define LCL_TabBar_Height ((LCLIsIphoneX) ? 83 : 49)

/** 底部横条高度 */
#define LCL_HomeIndicator_Height ((LCLIsIphoneX) ? 34 : 0)

但是这不能满足我们的需求, 因为这样做它不支持横屏。

3. 现在的做法

我们需要用到UIKit11.0的新增属性来完成这个需求

UIView类的新属性safeAreaLayoutGuide, 它是UILayoutGuide类型, 我们可以理解为一块安全区域(SafeArea), 不被statusBar, navigationBar, toolBar, tabBar所遮挡的区域。
UILayoutGuide类的属性layoutFrame, 安全区域的位置和大小。
UIView类的新属性SafeAreaInsets, 它指示的是这块安全区域距离整个屏幕之间的上下左右边距

首先我们可以先打印下这三个属性

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    CGRect frame = self.view.frame;
    NSLog(@"self.view - frame - %@", NSStringFromCGRect(frame));
    
    CGRect layoutFrame = self.view.safeAreaLayoutGuide.layoutFrame;
    NSLog(@"self.view - layoutFrame - %@", NSStringFromCGRect(layoutFrame));
    
    UIEdgeInsets insets = self.view.safeAreaInsets;
    NSLog(@"self.view - insets - %@", NSStringFromUIEdgeInsets(insets));
}

打印结果:
在iPhoneX竖屏(设备朝上)情况下输出为:

self.view - frame - {{0, 0}, {375, 812}}
self.view - layoutFrame - {{0, 88}, {375, 690}}
self.view - insets - {88, 0, 34, 0}

可以看到, 在竖屏情况下, 整个控制器的view的大小就是整个屏幕的大小, 而安全区域的大小为除去statusBar(状态栏区域:44), navigationBar(导航栏区域:44), home indicator(底部横条区域:34), 剩下的就是安全区域, 如图:
在这里插入图片描述
在iPhoneX横屏(设备朝左)情况下输出为:

self.view - frame - {{0, 0}, {812, 375}}
self.view - layoutFrame - {{44, 32}, {724, 322}}
self.view - insets - {32, 44, 21, 44}

可以看到, 在横屏情况下, 整个控制器的view的大小就是整个屏幕的大小, 而安全区域的大小为除去statusBar(状态栏区域:44), navigationBar(导航条区域:32), home indicator(底部横条区域:21), 剩下的就是安全区域, 如图:
在这里插入图片描述
在了解了这几个属性具体所指的内容之后, 我们也就可以开始UI布局和屏幕适配啦.

首先我们声明两个全局私有属性

@interface ViewController ()

/** 红色view 用于置顶 */
@property(nonatomic, strong) UIView *redView;

/** 橘色view 用于置底 */
@property(nonatomic, strong) UIView *orangeView;

@end
然后在viewDidLoad方法里面完成视图的创建

#pragma mark - 创建视图
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.title = @"屏幕适配";
    self.view.backgroundColor = [UIColor yellowColor];
    
    /** 创建红色view */
    UIView *redView = [UIView new];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    self.redView = redView;
    
    /** 创建橘色view */
    UIView *orangeView = [UIView new];
    orangeView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:orangeView];
    self.orangeView = orangeView;
}

之后在viewWillLayoutSubviews完成对视图的frame设置

#pragma mark - 设置视图frame
- (void)viewWillLayoutSubviews {
  
    /**
     layoutFrame.size.width 安全区域宽度
     layoutFrame.size.height 安全区域高度
     */
    CGRect layoutFrame = self.view.safeAreaLayoutGuide.layoutFrame;
    NSLog(@"self.view - layoutFrame - %@", NSStringFromCGRect(layoutFrame));
    
    /**
     inset.left 安全区域距离屏幕最左边的大小
     inset.right 安全区域距离屏幕最右边的大小
     inset.top 安全区域距离屏幕最上边的大小
     inset.bottom 安全区域距离屏幕最下边的大小
     */
    UIEdgeInsets insets = self.view.safeAreaInsets;
    
    /** 红色view置顶 */
    self.redView.frame = CGRectMake(insets.left, insets.top, layoutFrame.size.width, 100);
    
    /** 橘色view置底 */
    self.orangeView.frame = CGRectMake(insets.left, self.view.bounds.size.height - insets.bottom - 100, layoutFrame.size.width, 100);
}

现在我们这个简单的Demo适配就算完成啦, 不管是iPhoneX, 还是其它iOS设备, 不管是竖屏, 还是横屏, 都可以完美适配, 如图:
在这里插入图片描述
用一句名言来结束本节的探讨吧, 那就是”完美”!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: IOS 安全区域是指在 IOS 设备上,屏幕顶部和底部会有一些边距,这些边距是为了留出手机顶部的状态栏(包括电量、时间等信息)和底部的 Home 按钮的空间。在网页布局中,我们可以使用 `padding` 属性来给元素添加内边距,从而避开安全区域。例如,在 IOS 设备上,我们可以使用如下 CSS 代码来为页面添加内边距,从而使内容不会被状态栏遮挡: ```css body { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); } ``` 注意,上述代码仅适用于 IOS 设备,对于其他平台可能不适用。 ### 回答2: CSS中的iOS安全区域是指在使用苹果设备上的浏览器显示网页时,屏幕顶部和底部的安全区域,以适应设备的刘海屏、圆角屏或者底部虚拟 Home 键的存在。 为了确保网页内容不被覆盖或者裁剪,我们可以使用CSS的属性来处理iOS安全区域。其中一种方法是使用`env(safe-area-inset-top)`和`env(safe-area-inset-bottom)`属性来获取设备的安全区域尺寸,并将元素的位置和尺寸进行调整,以适应安全区域。 例如,可以通过设置`padding-top: env(safe-area-inset-top);`和`padding-bottom: env(safe-area-inset-bottom);`来为具有固定定位的元素添加上下内边距,并确保元素的内容不会被遮挡。 另外,我们还可以使用JavaScript来检测设备的安全区域尺寸,并动态地为元素添加适应性的样式。通过监听窗口的`resize`事件或者使用`window.matchMedia`方法来检测设备的屏幕方向和尺寸变化,然后根据具体情况动态地修改CSS样式。 总之,通过使用CSS和JavaScript,我们可以轻松地处理iOS设备的安全区域,确保网页内容在各种设备上都能正常显示,提升用户的浏览体验。 ### 回答3: CSS中的IOS安全区域是指在IOS设备上,屏幕上显示实际内容的安全区域。由于不同的IOS设备具有不同的屏幕尺寸和宽高比,因此为了确保内容的显示效果,在设计网页时需要考虑IOS安全区域的限制。 IOS安全区域的大小和位置是由设备的屏幕尺寸决定的。在设计时,应该避免将重要的内容或交互元素放置在安全区域之外,以免被屏幕的刘海、圆角等特殊形状遮挡。 为了确保网页在不同的IOS设备上正常显示,可以使用CSS的媒体查询来检测IOS设备,并根据不同的设备尺寸和宽高比来设置元素的大小、位置和布局。可以使用“env(safe-area-inset-top)”、“env(safe-area-inset-right)”、“env(safe-area-inset-bottom)”和“env(safe-area-inset-left)”等CSS变量来获取安全区域距离屏幕边缘的距离,然后使用这些值来调整元素的位置和尺寸,以适应不同的IOS设备。 此外,还可以使用CSS的属性“padding-top”、“padding-right”、“padding-bottom”和“padding-left”来设置元素的内边距,并结合安全区域的距离值,使元素在IOS安全区域内正常显示。还可以使用“fixed”定位或“sticky”定位来确保元素始终在安全区域内可见。 总而言之,通过在设计和布局中考虑IOS安全区域的限制,并使用CSS的媒体查询和相关属性来适应不同的IOS设备,可以确保网页在IOS设备上具有良好的显示效果和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值