React原生复活动画不适用于ios,适用于android



我有一个位于选项卡文本下的底部栏的动画,该动画在android中运行良好,但在ios中不正常。我用的是react native复活。如有任何帮助,我们将不胜感激。感谢

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>
);
}
})

这是我的代码,行动画。视图在iOS中没有动画,所以我不在那里渲染它,但我希望它能工作。

Android预期行为(安卓(

iOS:iOS 中的行为

我从自己的代码中观察到,这可能适用于也可能不适用于这里。只有当两个transform属性都使用react原生动画值时,此观察结果才成立。您的代码似乎与此场景相匹配。

仅在iOS中,我必须scale属性放在transform对象的translateX属性之前。如果我把translateX属性放在scale属性之前,那么translateX属性会受到阻碍。

我对此没有任何解释,但我已经用scaleX进行了测试,因为这就是您正在使用的,也是如此。

因此,为了清楚起见,以下工作:

<Animated.Value
style={[{
transform: [{
scale: animationValue1,
translateX: animationValue2,
}]
}]}
/>

下一步,scale工作,但translateX不工作:

<Animated.Value
style={[{
transform: [{
translateX: animationValue2,
scale: animationValue1,
}]
}]}
/>

你会注意到我的语法也和你的有点不同。据我所知,不应该将translateXscaleX属性放在style对象中而不封装在transform属性中,如上所述。也许复活的View与原生的反应有点不同。。如果在您尝试重新排序属性后它仍然不起作用,那么也要考虑一下。

请参阅此处的文档:https://reactnative.dev/docs/transforms#transform

这有点混乱,因为API将transform描述为一个函数,但页面顶部的示例显示了它的使用方式,正如我在上面所做的那样。

最新更新