Анимировать взад и вперед повернуть на логотип нажмите с реагировать родной - PullRequest
0 голосов
/ 24 февраля 2019

Я пытаюсь анимировать логотип меню для поворота при нажатии.Я успешно получаю вращение, когда оно вращается вверх, но оно просто переходит в 0 при вращении вниз, вместо того, чтобы проходить анимацию вращения.

Это мой компонент:

import React from 'react';
import { TouchableOpacity, Animated } from 'react-native';
import PropTypes from 'prop-types';

import styles from './styles';

const TabIcon = ({
  route,
  renderIcon,
  onPress,
  focused,
  menuToggled,
  activeTintColor,
  inactiveTintColor,
}) => {
  const isMenuLogo = route.params && route.params.navigationDisabled;
  const animation = new Animated.Value(0);

  Animated.timing(animation, {
    toValue: menuToggled ? 1 : 0,
    duration: 200,
    useNativeDriver: true,
  }).start();

  const rotateInterpolate = animation.interpolate({
    inputRange: [0, 1],
    outputRange: ['0deg', '180deg'],
  });
  const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
  const logoStyles = [animatedStyles, styles.logoStyle];

  return (
    <TouchableOpacity
      style={styles.tabStyle}
      onPress={onPress}
      activeOpacity={isMenuLogo && 1}
    >
      <Animated.View style={isMenuLogo ? logoStyles : null}>
        {
          renderIcon({
            route,
            focused,
            tintColor: focused
              ? activeTintColor
              : inactiveTintColor,
          })
        }
      </Animated.View>
    </TouchableOpacity>
  );
};

TabIcon.propTypes = {
  route: PropTypes.shape({
    key: PropTypes.string,
  }).isRequired,
  renderIcon: PropTypes.func.isRequired,
  onPress: PropTypes.func,
  focused: PropTypes.bool,
  menuToggled: PropTypes.bool,
  activeTintColor: PropTypes.string.isRequired,
  inactiveTintColor: PropTypes.string.isRequired,
};

TabIcon.defaultProps = {
  onPress: () => {},
  focused: false,
  menuToggled: false,
};

export default TabIcon;

Сначала я проверяю, было ли это переключено, прежде чем вращать.Этот компонент вызывается в другом родительском компоненте, отображающем пользовательскую навигацию по нижней вкладке.

Должна ли я создавать другую анимацию для него, когда он вращается вниз или в текущей анимации отсутствует конфигурация?

Любая помощь и предложение будут очень признательны.Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Я пробовал решение Эндрю выше, и оно работает, но я решил превратить его в компонент класса.Это работает так же.См. Компонент ниже.

import React, { PureComponent } from 'react';
import { TouchableOpacity, Animated } from 'react-native';
import PropTypes from 'prop-types';

import styles from './styles';

class TabIcon extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      animation: new Animated.Value(0),
    };
  }

  render() {
    const { animation } = this.state;
    const {
      route,
      renderIcon,
      onPress,
      focused,
      menuToggled,
      activeTintColor,
      inactiveTintColor,
    } = this.props;
    const isMenuLogo = route.params && route.params.navigationDisabled;

    Animated.timing(animation, {
      toValue: menuToggled ? 1 : 0,
      duration: 200,
      useNativeDriver: true,
    }).start();

    const rotateInterpolate = animation.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '180deg'],
    });
    const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
    const logoStyles = [animatedStyles, styles.logoStyle];

    return (
      <TouchableOpacity
        style={styles.tabStyle}
        onPress={onPress}
        activeOpacity={isMenuLogo && 1}
      >
        <Animated.View style={isMenuLogo ? logoStyles : null}>
          {
            renderIcon({
              route,
              focused,
              tintColor: focused
                ? activeTintColor
                : inactiveTintColor,
            })
          }
        </Animated.View>
      </TouchableOpacity>
    );
  }
}

TabIcon.propTypes = {
  route: PropTypes.shape({
    key: PropTypes.string,
  }).isRequired,
  renderIcon: PropTypes.func.isRequired,
  onPress: PropTypes.func,
  focused: PropTypes.bool,
  menuToggled: PropTypes.bool,
  activeTintColor: PropTypes.string.isRequired,
  inactiveTintColor: PropTypes.string.isRequired,
};

TabIcon.defaultProps = {
  onPress: () => {},
  focused: false,
  menuToggled: false,
};

export default TabIcon;
0 голосов
/ 24 февраля 2019

Я думаю, что проблема связана с тем фактом, что когда вы устанавливаете начальное значение animation, поскольку оно всегда установлено на 0, оно не отражает изменения при переключении меню.

Вам нужно изменить:

const animation = new Animated.Value(0);

на

const animation = new Animated.Value(menuToggled ? 0 : 1);

Хотя внесение этого изменения вызовет другую проблему.Поскольку menuToggled влияет на начальную и конечную позиции анимации, значок теперь будет поворачиваться в правильную начальную позицию из конечной позиции.Это не идеально.

Однако мы можем это исправить, установив значение по умолчанию null для menuToggled.Затем оборачиваем анимацию в if-statement, который запускается, только если menuToggled не null.

Вот пример, основанный на вашем исходном коде:

import React from 'react';
import { View, StyleSheet, Animated, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

const TabIcon = ({
  onPress,
  menuToggled
}) => {
  const logoStyles = [styles.logoStyle];
  if (menuToggled !== null) {
    const animation = new Animated.Value(menuToggled ? 0 : 1);

    Animated.timing(animation, {
      toValue: menuToggled ? 1 : 0,
      duration: 200,
      useNativeDriver: true
    }).start();

    const rotateInterpolate = animation.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '180deg']
    });
    const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
    logoStyles.push(animatedStyles);
  }

  return (
    <TouchableOpacity
      style={styles.tabStyle}
      onPress={onPress}
    >
      <Animated.View style={logoStyles}>
        <Ionicons name="md-checkmark-circle" size={32} color="green" />
      </Animated.View>
    </TouchableOpacity>
  );
};
export default class App extends React.Component {
  state = {
    menuToggled: null
  }

  toggleMenu = () => {
    this.setState(prevState => {
      return { menuToggled: !prevState.menuToggled };
    });
  }

  render () {
    return (
      <View style={styles.container}>
        <TabIcon
          onPress={this.toggleMenu}
          menuToggled={this.state.menuToggled}
        />
      </View>
    );
  }
}

Iудалил ваш TabIcon компонент, так как там было много вещей, которые не были связаны с анимацией.Вы легко сможете включить то, что я сделал, в свой собственный компонент.https://snack.expo.io/@andypandy/rotating-icon

...