uniapp小程序,适配苹果底部黑条虚拟键,适配安全区域

 最近写小程序的时候,遇到了 iPhoneX底部小黑条与页面内容重叠的问题,其实就是iPhoneX底部安全区域的适配问题,总结一下适配iPhoneX及以上机型的底部安全区域适配方案。

前言

在苹果 iPhoneX 、iPhone XR及以上设备上,底部的物理Home键被取消,改为底部小黑条替代home键功能。微信小程序需要针对这种情况进行适配,否则可能会遇到底部按钮或选项卡栏与底部小黑条重叠的情况,如下图。

         

安全区域是什么意思 ?

想要解决内容与小黑条重叠的问题,我们需要先了解清楚苹果对于安全区域的定义。

安全区域指的是一个可视窗口范围,处于安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)的影响。

下图是苹果官方给的图,另外 安全区域是在IOS11并且是iPhoneX及以上机型才有的,所以只需要适配这类机型。

 

这里我就给大家介绍一下比较常用的两种适配方案。

方案一:使用微信官方API,getSystemInfoSync函数进行适配

通过该API可以获取到屏幕的高度

还有竖屏正方向下的安全区域 safeArea对象的bottom属性

1. 为了方便使用我们需要创建一个全局存储高度的属性:bottomHeight

// 数据都是根据当前机型进行计算,这样的方式兼容大部分机器,导航栏、胶囊获取可无视,需要自取
globalData: {
	// navBarHeight: 0, // 导航栏高度
	// menuRight: 0, // 胶囊距右方间距(方保持左、右间距一致)
	// menuTop: 0, // 胶囊距顶部间距
	// menuHeight: 0, // 胶囊高度(自定义内容可与胶囊高度保证一致)
    bottomHeight: 0 // 底部安全区域高度
},

2. 在App.vue 的 onLaunch函数中添加以下代码获取值

onLaunch: function () {
	const that = this
	// 获取系统信息
	const systemInfo = uni.getSystemInfoSync()
    that.globalData.bottomHeight = systemInfo.screenHeight - systemInfo.safeArea.bottom
	// 胶囊按钮位置信息
	// const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
	// 导航栏高度 = 状态栏高度 + 44
	// that.globalData.navBarHeight = systemInfo.statusBarHeight + systemInfo.safeArea.top
	// that.globalData.menuRight = systemInfo.screenWidth - menuButtonInfo.right
	// that.globalData.menuTop = menuButtonInfo.top;
	// that.globalData.menuHeight = menuButtonInfo.height;


    // getSystemInfo函数同样可以拿到,这个是 异步获取系统信息
    uni.getSystemInfo({
        success: (res) => {
          console.log(res);
          that.globalData.bottomHeight = res.screenHeight - res.safeArea.bottom
        }
    })
}

3. 在需要兼容底部安全区域的 vue文件中的onLoad函数中获取设置的全局变量安全区域高度 bottomHeight

onLoad() {
   // 注意需要使用getApp()去获取全局变量
   this.bottomHeight = getApp().globalData.bottomHeight
},

 4. 最后在所需页面的结构里添加以下代码就完成了苹果的底部安全区域适配

<view class="container" :style="{ paddingBottom: bottomHeight + 'px' }"></view>

方案二:使用苹果官方推出的适配方案css函数env()、constant()来适配

苹果官方推荐使用env(),constant()来适配,建议使用该方案,不需要管数值具体是多少。

env()和constant(),是IOS11新增特性,Webkit的css函数,用于设定安全区域与边界的距离,有4个预定义变量:

safe-area-inset-left:安全区域距离左边边界的距离
safe-area-inset-right:安全区域距离右边边界的距离
safe-area-inset-top:安全区域距离顶部边界的距离
safe-area-inset-bottom :安全距离底部边界的距离

注意:env()和constant()函数有个必要的使用前提,当网页设置viewport-fit=cover的时候才生效,根据微信小程序的表现和我在实际真机测试时这两个函数生效,推测小程序里的viewport-fit默认是cover。

还有一点,在IOS11.2系统以前,可以使用constant()函数,但是在IOS11.2系统以后,这个函数就被废弃了,被env()函数替代了。

所以我们在做屏幕适配时,需要这样写:

// 写在需要添加底部边距的盒子上
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/

如果我们需要额外的距离也可以使用calc函数来写:

padding-bottom: calc(constant(safe-area-inset-bottom) + 50rpx); /*兼容 IOS<11.2*/
padding-bottom: clac(env(safe-area-inset-bottom) + 50rpx); /*兼容 IOS>11.2*/
// 就是在适配底部小黑条的基础上又增加了50rpx的底部内边距

 适配后的页面:

                                 

**注意:**env()和constant()需要同时存在,而且顺序不能换。

### 实现 UniApp 应用中顶部安全区域适配 为了确保应用程序能够在不同设备上正确显示,特别是在带有异形屏(如iPhone X及以上型号)的设备上,可以利用 `env()` 函数来动态调整页面布局。对于顶部的安全区域适配,在编写样式时可以通过设置内边距或外边距的方式处理。 #### 使用 CSS 进行适配 通过CSS中的`padding-top`属性配合`env(safe-area-inset-top)`函数能够有效地防止内容被状态栏遮挡: ```css /* 定义全局容器 */ .page-container { padding-top: env(safe-area-inset-top); /* 动态适应顶部安全区高度 */[^1] } ``` 此方法适用于大多数场景下的简单页面结构,只需将上述类名应用于根节点即可自动完成适配工作。 #### 配置 manifest.json 文件 除了前端样式的修改之外,还可以进一步优化用户体验,即在项目根目录下找到`manifest.json`文件并做如下配置: ```json { ... "app-plus": { "safearea": { "background": "#ffffff", "top": { "offset": "auto" } } }, ... } ``` 这段JSON代码的作用是在应用启动时自动生成一个与屏幕顶端相匹配的高度作为预留空间,从而避免重要内容被系统UI组件覆盖的情况发生[^3]。 #### JavaScript 动态计算 如果遇到更复杂的需求,则可能需要借助JavaScript来进行更加精细的操作。比如可以在页面加载完成后执行一段脚本以获取当前环境的具体参数值,并据此作出相应调整: ```javascript // 获取视口信息对象 const viewport = uni.getSystemInfoSync(); if (viewport.safeAreaInsets && viewport.safeAreaInsets.top > 0){ document.querySelector('.custom-header').style.paddingTop = `${viewport.safeAreaInsets.top}px`; } ``` 这种方法允许开发者针对特定件灵活响应不同的设备特性,提供更为个性化的视觉效果和交互体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值