Как передать свойства навигации в createStackNavigator для использования заголовка по умолчанию с анимацией

Последние несколько дней я работал над добавлением анимированного заголовка на свои экраны. Мне это удалось, однако теперь я хотел бы применить это как свой заголовок по умолчанию, а не копировать и вставлять код на все экраны, которые я хочу использовать. На данный момент анимированный заголовок реализован на экране следующим образом:

Чтобы отобразить заголовок:

static navigationOptions = ({ navigation }) => {
    return {
        header: () => {
            return (
                <SafeAreaView style={{
                    height: 0,
                    overflow: 'visible',
                }}>
                    <Animated.View style={{height: 80, width: 80,
                        transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
                    }}>
                        <TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
                            <Icon.Ionicons  style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
                        </TouchableOpacity>
                    </Animated.View>
                </SafeAreaView>
            )
        }
    }
};

Чтобы настроить состояние:

constructor() {
    super();
    this.state = {
        headerScrollY: new Animated.Value(0),
    };
}

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

componentWillMount() {
    this.props.navigation.setParams({
        headerScrollY: this.state.headerScrollY.interpolate({
            inputRange: [0, 80],
            outputRange: [0, -80],
        })
    });
}

Основной метод рендеринга с "scrollView", вызывающим событие "onScroll" для выполнения действия прокрутки.

render() {
    return (
            <ScrollView
                style={Styles.wholePageContainer}
                showsVerticalScrollIndicator={false}
                scrollEventThrottle={16}
                onScroll={Animated.event( [{nativeEvent:{contentOffset: {y: this.state.headerScrollY}}}])}
            >
                ...
            </ScrollView>
        );
    }

Чтобы установить заголовок по умолчанию, я должен установить значение «header» для «defaultNavigationOptions», когда я использую «createStackNavigator». Я могу использовать это для создания простого defaultHeader красного цвета с высотой 100 (код и изображение ниже):

const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Category: CategoryScreen,
    Venue: VenueScreen,
    Activity: ActivityScreen,
}, {
    headerMode: 'screen',
    defaultNavigationOptions: {
        header: <View style={{backgroundColor: '#ff0000', height: 100}} />
        ,
    },
});

Симулятор, демонстрирующий применение простого заголовка по умолчанию

К сожалению, для моего анимированного заголовка мне нужна опора «навигация», поскольку она используется для хранения значений анимации. Я пробовал много подходов, чтобы передать это туда, где мне нужны значения, и мне было интересно, знает ли кто-нибудь, как это сделать, и возможно ли это вообще, или есть ли у кого-нибудь какие-либо предложения.


person Jamie Shepherd    schedule 22.03.2019    source источник
comment
вы пробовали это: defaultNavigationOptions: ({ navigation }) => ({ header: <YourHeader navigation={navigation} /> })   -  person Hend El-Sahli    schedule 22.03.2019
comment
Потрясающе, это сработало! Большое Вам спасибо. Я пробовал много подобных вариантов, однако из-за того, что в документации говорилось, что заголовок должен быть функцией, я всегда делал эту функцию, в которой я пытался получить реквизиты навигации, где я должен был перейти на 1 этап по ссылке, как вы предложили. Я выложу рабочий код ниже.   -  person Jamie Shepherd    schedule 22.03.2019
comment
Удачного кодирования :)   -  person Hend El-Sahli    schedule 22.03.2019


Ответы (1)


Благодаря Хенду Эль-Сахли у меня теперь есть код, который работает должным образом. Результат (для использования в будущем) такой же, как и раньше, однако после удаления определений заголовков в параметрах навигации для каждого экрана и вызова createStackNavigator будет следующее:

const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Category: CategoryScreen,
    Venue: VenueScreen,
    Activity: ActivityScreen,
}, {
    headerMode: 'screen',
    defaultNavigationOptions: ({ navigation }) => ({
        header:
            <SafeAreaView style={{
                height: 0,
                overflow: 'visible',
            }}>
                <Animated.View style={{height: 80, width: 80,
                    transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
                }}>
                    <TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
                        <Icon.Ionicons  style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
                    </TouchableOpacity>
                </Animated.View>
            </SafeAreaView>
    }),
});
person Jamie Shepherd    schedule 22.03.2019
comment
Моя (глупая) ошибка заключалась в том, что я использовал headerLeft: ({navigation}) => , которого не существует! Использование defaultNavigationOptions: ({ navigation }) => решило проблему! Спасибо! - person Aleksandar; 28.08.2019