我有一个底部栏的动画,位于选项卡文本下方,该动画在 android 中工作正常,但在 ios 中不行。我正在使用react-native-reanimated。 任何帮助,将不胜感激。 谢谢
const MyTabBar = React.memo((props) => {
const {state, descriptors, navigation, position, setEnableSwipe, swipeEnabled, layout, theme, auth, ui} = props;
if (state.routes[state.index].state && state.routes[state.index].state.index !== 0) {
if (swipeEnabled === true) {
setEnableSwipe(false)
}
return null;
}
else {
if (swipeEnabled === false) {
setEnableSwipe(true);
}
var tabWidth = (layout.width - 50)/3
const left = Animated.interpolate(position, {
inputRange: [0, 1, 2],
outputRange: [(tabWidth - 50)/2 , tabWidth + (tabWidth - 50)/2, 2*tabWidth + (tabWidth - 50)/2]
});
const length = Animated.interpolate(position, {
inputRange: [0, 0.5, 1, 1.5, 2],
outputRange: [0.3, 1, 0.3, 1, 0.3],
})
return (
<View style={{ flexDirection: 'row', backgroundColor: Platform.OS === 'ios' && ui.showing_modal ? 'white' : 'white', alignItems: 'center' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
const inputRange = state.routes.map((_, i) => i);
const opacity = Animated.interpolate(position, {
inputRange,
outputRange: inputRange.map(i => (i === index ? 1 : 0.4)),
});
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityStates={isFocused ? ['selected'] : []}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{flex: 1}}
>
<Animated.Text style={{
opacity,
fontWeight: index === state.index ? '600' : 'normal',
fontSize: index === state.index ? 19 : 17,
textAlign: 'center',
}}>
{label}
</Animated.Text>
</TouchableOpacity>
);
})}
{Platform.OS === 'ios' && false ?
<View/> : <Animated.View
style={{
backgroundColor: theme.primaryColor,
translateX: left,
scaleX: length,
height: 4,
width: 50,
position: 'absolute',
bottom: 0,
borderRadius: 10,
}} />}
<TouchableOpacity
style={{minWidth: 50, maxWidth: 50}}
onPress={() => {
switch (state.index) {
case 0:
navigation.navigate('AddSchedule');
break;
case 1:
navigation.navigate('AddScene');
break;
case 2:
if (auth.accesstoken) {
navigation.navigate('NewGeoscene');
} else {
ReactNativeHapticFeedback.trigger('notificationWarning', {
ignoreAndroidSystemSettings: true,
enableVibrateFallback: true
})
}
break;
default:
//
}
}}
>
<Text style={{fontSize: 36, color: theme.primaryColor}}> + </Text>
</TouchableOpacity>
</View>
);
}
})
这是我的代码,Animated.View 行在 iOS 中没有动画,所以我没有在那里渲染它,但我希望它能工作。
我从我自己的代码中得到了一个观察结果,它可能适用也可能不适用于此处。仅当两个
transform
属性都使用react-native-reanimated 动画值时,此观察结果才成立。您的代码似乎符合此场景。
仅在 iOS 中,我必须将
scale
属性放在 translateX
对象中的 transform
属性之前。如果我将 translateX
属性放在 scale
属性之前,则 translateX
属性将受到阻碍。
我对此没有解释,但我已经用
scaleX
测试过它,因为这就是你正在使用的,也是如此。
为了清楚起见,以下内容有效:
<Animated.Value
style={[{
transform: [{
scale: animationValue1,
translateX: animationValue2,
}]
}]}
/>
..在接下来的过程中,
scale
可以工作,但translateX
不起作用:
<Animated.Value
style={[{
transform: [{
translateX: animationValue2,
scale: animationValue1,
}]
}]}
/>
您会注意到我的语法也与您的略有不同。据我所知,您不应该将
translateX
和 scaleX
属性放入 style
对象中,而不将其包装在 transform
属性中,如上所述。也许 reanimated 的 View
的工作方式与原生的原生工作方式略有不同。如果在尝试重新排序属性后它仍然不起作用,那么也请考虑一下。
请参阅此处的文档:https://reactnative.dev/docs/transforms#transform
这有点令人困惑,因为 API 将
transform
描述为一个函数,但页面顶部的示例显示了它的使用方式,就像我上面所做的那样。
这是否意味着布局动画也可以重新启动 3。我遇到了同样的问题,在 android 上工作正常,但在 IOS 上却不行。
<Animated.View entering={FadeInDown.duration(500)} style={{position:'absolute', bottom:50, width:'100%'}}>
<Pressable
style={({pressed})=>[styles.btn, pressed ? {opacity:.8} : '' ]}>
<Text style={{alignSelf:'center', color:'#ffffff', fontSize:hp('2.5%'), fontWeight:'500', textTransform:'uppercase'}}>Buy Ticket</Text>
</Pressable>
</Animated.View>