微信小程序适配iPhoneX及后续型号底部小黑条(底部安全区域)
适配问题
自 iPhone X 开始,底部增加了小黑条,也就是安全区域,微信小程序官方已经针对 iPhoneX 及后续型号的底部小黑条做了适配,小程序底部的 tabbar 不会被黑条遮挡,但是其他页面自定义的底部导航,还需要我们自己来解决。
先看效果图
解决方案
大概的解决方案是根据不同手机型号,判断是否需要增加CSS样式,然后利用 padding-bottom 或 height 来处理导航的位置。
相关代码
1. 判断手机型号
在 app.js 的 onLaunch 函数内调用 wx.getSystemInfo 获得手机型号,并存储为全局变量:
onLaunch: function() { var _this = this; //Yangjunwei-5839:iPhoneX及以后型号适配底部黑线问题 S //var sdkVersion = wx.getSystemInfoSync().SDKVersion; //从基础库 2.20.1 开始,本接口停止维护,请使用 wx.getAppBaseInfo 代替 var sdkVersion = wx.getAppBaseInfo().SDKVersion; //基础库版本不低于 2.21.3 console.log("app.js / sdkVersion 基础库: ", sdkVersion); if( _this.compareVersion(sdkVersion, '2.21.3') >= 0 ){ var deviceInfo = wx.getDeviceInfo(); var deviceModel = deviceInfo.model; console.log("app.js / wx.getDeviceInfo: ", deviceInfo); //查询设备型号是否包含如下几个型号,包含则注明,可在后续添加CSS样式 if( deviceModel.search('iPhone X') != -1 ){ _this.setCache("isIpx", deviceModel); } else if( deviceModel.search('iPhone 11') != -1 ){ _this.setCache("isIpx", deviceModel); } else if( deviceModel.search('iPhone 12') != -1 ){ _this.setCache("isIpx", deviceModel); } else if( deviceModel.search('iPhone 13') != -1 ){ _this.setCache("isIpx", deviceModel); } else if( deviceModel.search('iPhone 14') != -1 ){ _this.setCache("isIpx", deviceModel); } else if( deviceModel.search('iPhone 15') != -1 ){ _this.setCache("isIpx", deviceModel); } else{ _this.setCache("isIpx", ""); } } else{ wx.getSystemInfo({ success: function(t) { console.log("app.js / wx.getSystemInfo: ", t); "0" == t.model.indexOf("iPhone X") ? _this.setCache("isIpx", t.model) : _this.setCache("isIpx", ""); } }); } //Yangjunwei-5839:iPhoneX及以后型号适配底部黑线问题 E ………… }, //小程序基础库版本比较 compareVersion: function(e, n) { e = e.split("."), n = n.split("."); for (var o = Math.max(e.length, n.length); e.length < o; ) e.push("0"); for (;n.length < o; ) n.push("0"); for (var s = 0; s < o; s++) { var t = parseInt(e[s]), i = parseInt(n[s]); if (t > i) return 1; if (t < i) return -1; } return 0; }, getCache: function(e, t) { var a = +new Date() / 1e3, i = ""; a = parseInt(a); try { (i = wx.getStorageSync(e + this.globalData.appid)).expire > a || 0 == i.expire ? i = i.value : (i = "", this.removeCache(e)); } catch (e) { i = void 0 === t ? "" : t; } return i = i || ""; }, setCache: function(e, t, a) { var i = +new Date() / 1e3, n = !0, o = { expire: a ? i + parseInt(a) : 0, value: t }; try { wx.setStorageSync(e + this.globalData.appid, o); } catch (e) { n = !1; } return n; },
2. 所需页面根据型号调用CSS样式
在所需页面的 .js 文件的 onLoad 或 onShow 函数内,根据上一步的全局变量 isIpx 存储的手机型号值,判断自定义底部导航是否需要调用 CSS 样式,样式名为 fui-iphonex-navbar
var o = getApp(); onLoad: function() { if( app.getCache("isIpx") ){ this.setData({ iphonexnavbar: "fui-iphonex-navbar" }) } } onShow: function () { if( app.getCache("isIpx") ){ this.setData({ iphonexnavbar: "fui-iphonex-navbar" }) } }
在所需页面的 .wxml 文件中,添加样式 {{iphonexnavbar}}
3. 添加CSS样式
在 app.wxss 中新增如下代码
/*Yangjunwei-5839: 防止苹果手机底部小黑条遮挡 2024.05.07 S*/ .fui-iphonex-navbar{ bottom:68rpx !important; } /*Yangjunwei-5839: E*/
拓展一下
可以利用 iOS 新增的 “viewport-fit” 特性或 “env() 和 constant()” 特性,结合 iPhone 各种设备尺寸及数据表来实现。