写这篇文章的原因,就是产品经理希望在app下方的tab上悬浮一条提示,我们的app用的是RN的框架,于是我调研了一番如何去计算底部tab栏的高度。去RN的社区逛了一圈,发现目前没有官方的方法能够直接调用得到底部tab高度,甚至还看到有人因为这一点而不满RN的开发人员,在社区吐槽(Trash Talk)。Anyway,那我们就自己来。
一、Tab栏自身的高度
这个地方去看了源码,发现tab的高度其实只有两个预设值,就是针对 iphpne || ipad做了判断,直接上相关源码。
const tabBarStyle = [
styles.tabBar,
this._shouldUseHorizontalLabels() && !Platform.isPad
? styles.tabBarCompact
: styles.tabBarRegular,
style,
];
const DEFAULT_HEIGHT = 49;
const COMPACT_HEIGHT = 29;
// 样式表
iconWithExplicitHeight: {
height: Platform.isPad ? DEFAULT_HEIGHT : COMPACT_HEIGHT,
},
二、关于IphoneX系列的SafeArea
iphone的底部会自增一个安全区域,那么安全区域的高度是多少呢,继续看源码。
LandScape Mode // 横屏模式
paddingLeft: 44
paddingRight: 44
paddingBottom: 24
paddingTop: 0
Portrait Mode // 竖屏模式
paddingLeft: 0
paddingRight: 0
paddingBottom:34
paddingTop:44 // ... Including Status bar height
可以看到底部的安全区域只对横竖屏做了处理,但是亲测,对iphoneX系列不同deviceHeight的机型,安全区域不一样。对于iPhonex/iPhoneXS,paddingBottom: 34,但是对于iPhoneXR/XS MAX,paddingBottom: 24,即iphonexr/xs max竖屏模式下被判断成横屏了。
三、总结
所以,对于安卓,你只需要得到tab的高度,然后绝对定位,不需要做特殊处理。对于iphone,你需要区别 iphoneX系列。
const styles = StyleSheet.create({
bottomView : {
position : "absolute",
bottom : isIphoneXOrXS() ? dp(tab高度 + 34) : ( isIphoneXROrXSMax() ? dp(tab高度 + 24) : dp(tab高度) ),
},
})
插句题外话,tab高度的获取,我是直接用模拟器的toggle inspetor得到的。
四、补充对iphoneX系列手机的css判断方法
// iPhone X、iPhone XS
var isIPhoneX = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 375 && window.screen.height === 812;
// iPhone XS Max
var isIPhoneXSMax = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 414 && window.screen.height === 896;
// iPhone XR
var isIPhoneXR = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 2 && window.screen.width === 414 && window.screen.height === 896;
五、小彩蛋
来看看社区里是怎么说的吧。 brentvatne是该框架的维护者之一。
以及社区里有人写了组件去判断tabbar的高度,对于博主的项目没有什么帮助,但是可能会对大家有用,需要的话可以链接里自取。https://github.com/react-navigation/tabs/issues/97
到这里,完结。撒花~