#ios #react-native #animation #react-native-ios #react-native-reanimated
#iOS #реагировать-родной #Анимация #react-native-ios #react-native-реанимированная #react-native
Вопрос:
У меня есть анимация для нижней панели, которая находится под текстом вкладки, анимация отлично работает в 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 amp;amp; 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' amp;amp; 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 amp;amp; !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' amp;amp; 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>
);
}
})
это мой код, строка анимирована.View не анимируется в iOS, поэтому я не рендерю его там, но я хочу, чтобы он работал.
Ожидаемое поведение Android (android)
iOS: поведение в iOS
Ответ №1:
У меня есть наблюдение из моего собственного кода, которое может быть или не быть применимо здесь. Это наблюдение справедливо только в том случае, если оба transform
свойства используют значения react-native-reanimated animation. Ваш код, похоже, соответствует этому сценарию.
Только в 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
and scaleX
в style
объект, не будучи обернутыми в transform
свойство, как указано выше. Возможно, reanimated View
работает немного иначе, чем родной для react native.. Если она все еще не работает после того, как вы попытаетесь изменить порядок свойств, подумайте и об этом.
Смотрите документацию здесь: https://reactnative.dev/docs/transforms#transform
Это немного запутано, потому что API описывается transform
как функция, но пример в верхней части страницы показывает, что он используется так, как я сделал выше.
Комментарии:
1. Спасибо. Когда я переместил translateX в transform, это устранило проблему. Я не перемещал масштаб, чтобы преобразовать его, он все равно работал. И, таким образом, не сталкивался с проблемой, вызванной заказом. Я переместу масштаб внутрь, спасибо за ввод