在React Native iOS中,我想在下图中滑入和滑出一个like。在下面的示例中,当按下按钮时,Payment Information视图从底部弹出,当按下折叠按钮时,它返回并消失。这样做的正确和适当的方法是什么?
Payment Information
先谢谢你!
编辑
58wvjzkj1#
基本上,你需要把你的视图绝对定位到屏幕的底部,然后你平移它的y值使其等于它的高度。(子视图必须有一个特定的高度,以便知道它移动了多少)代码:
'use strict'; import React, {Component} from 'react'; import ReactNative from 'react-native'; const { AppRegistry, StyleSheet, Text, View, TouchableHighlight, Animated } = ReactNative; var isHidden = true; class AppContainer extends Component { constructor(props) { super(props); this.state = { bounceValue: new Animated.Value(100), //This is the initial position of the subview buttonText: "Show Subview" }; } _toggleSubview() { this.setState({ buttonText: !isHidden ? "Show Subview" : "Hide Subview" }); var toValue = 100; if(isHidden) { toValue = 0; } //This will animate the transalteY of the subview between 0 & 100 depending on its current state //100 comes from the style below, which is the height of the subview. Animated.spring( this.state.bounceValue, { toValue: toValue, velocity: 3, tension: 2, friction: 8, } ).start(); isHidden = !isHidden; } render() { return ( <View style={styles.container}> <TouchableHighlight style={styles.button} onPress={()=> {this._toggleSubview()}}> <Text style={styles.buttonText}>{this.state.buttonText}</Text> </TouchableHighlight> <Animated.View style={[styles.subView, {transform: [{translateY: this.state.bounceValue}]}]} > <Text>This is a sub view</Text> </Animated.View> </View> ); } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', marginTop: 66 }, button: { padding: 8, }, buttonText: { fontSize: 17, color: "#007AFF" }, subView: { position: "absolute", bottom: 0, left: 0, right: 0, backgroundColor: "#FFFFFF", height: 100, } }); AppRegistry.registerComponent('AppContainer', () => AppContainer);
ltskdhd12#
我知道这有点晚了,但是我想它可能对某些人有用。你应该试试一个叫做rn-sliding-out-panel的组件。它工作得非常好。https://github.com/octopitus/rn-sliding-up-panel
rn-sliding-out-panel
<SlidingUpPanel draggableRange={top: 1000, bottom: 0} showBackdrop={true|false /*For making it modal-like*/} ref={c => this._panel = c} visible={ture|false /*If you want it to be visible on load*/} ></SlidingUpPanel>
您甚至可以通过外部按钮打开它:
<Button onPress={()=>{this._panel.transitionTo(1000)}} title='Expand'></Button>
您可以通过npm安装它:sudo npm install rn-sliding-out-panel --save位于您的react-native根目录上。我希望它能对某人有所帮助:D
sudo npm install rn-sliding-out-panel --save
t1qtbnec3#
我创建了一个可重用的BottomSheet组件,它接受任何内容。它看起来是这样的:
BottomSheet
下面是BottomSheet组件的代码(TypeScript格式):
import * as React from 'react' import { Animated, Easing, Pressable, StyleSheet, useWindowDimensions, View, } from 'react-native' const DEFAULT_HEIGHT = 300 function useAnimatedBottom(show: boolean, height: number = DEFAULT_HEIGHT) { const animatedValue = React.useRef(new Animated.Value(0)) const bottom = animatedValue.current.interpolate({ inputRange: [0, 1], outputRange: [-height, 0], }) React.useEffect(() => { if (show) { Animated.timing(animatedValue.current, { toValue: 1, duration: 350, // Accelerate then decelerate - https://cubic-bezier.com/#.28,0,.63,1 easing: Easing.bezier(0.28, 0, 0.63, 1), useNativeDriver: false, // 'bottom' is not supported by native animated module }).start() } else { Animated.timing(animatedValue.current, { toValue: 0, duration: 250, // Accelerate - https://easings.net/#easeInCubic easing: Easing.cubic, useNativeDriver: false, }).start() } }, [show]) return bottom } interface Props { children: React.ReactNode show: boolean height?: number onOuterClick?: () => void } export function BottomSheet({ children, show, height = DEFAULT_HEIGHT, onOuterClick, }: Props) { const { height: screenHeight } = useWindowDimensions() const bottom = useAnimatedBottom(show, height) return ( <> {/* Outer semitransparent overlay - remove it if you don't want it */} {show && ( <Pressable onPress={onOuterClick} style={[styles.outerOverlay, { height: screenHeight }]} > <View /> </Pressable> )} <Animated.View style={[styles.bottomSheet, { height, bottom }]}> {children} </Animated.View> </> ) } const styles = StyleSheet.create({ outerOverlay: { position: 'absolute', width: '100%', zIndex: 1, backgroundColor: 'black', opacity: 0.3, }, bottomSheet: { position: 'absolute', width: '100%', zIndex: 1, // Here you can set a common style for all bottom sheets, or nothing if you // want different designs backgroundColor: 'dodgerblue', borderRadius: 16, }, })
我把这段代码放在一个名为BottomSheet.tsx的文件中。BottomSheet的使用方法如下:
BottomSheet.tsx
import * as React from 'react' import { Pressable, SafeAreaView, StatusBar, StyleSheet, Text, View, } from 'react-native' import { BottomSheet } from './src/BottomSheet' const App = () => { const [showBottomSheet, setShowBottomSheet] = React.useState(false) const hide = () => { setShowBottomSheet(false) } return ( <SafeAreaView style={styles.safeAreaView}> <StatusBar barStyle={'dark-content'} /> <View style={styles.container}> <Pressable onPress={() => { setShowBottomSheet(true) }} style={styles.showButton} > <Text style={styles.buttonText}>Show bottom sheet</Text> </Pressable> </View> <BottomSheet show={showBottomSheet} height={290} onOuterClick={hide}> <View style={styles.bottomSheetContent}> <Text style={styles.bottomSheetText}>Hey boys, hey girls!</Text> <Pressable onPress={hide} style={styles.bottomSheetCloseButton}> <Text style={styles.buttonText}>X Close</Text> </Pressable> </View> </BottomSheet> </SafeAreaView> ) } const styles = StyleSheet.create({ safeAreaView: { flex: 1, }, container: { flex: 1, }, showButton: { marginTop: 48, padding: 16, backgroundColor: 'mediumspringgreen', alignSelf: 'center', borderRadius: 8, }, buttonText: { fontSize: 20, }, bottomSheetContent: { padding: 40, alignItems: 'center', }, bottomSheetText: { fontSize: 24, marginBottom: 80, }, bottomSheetCloseButton: { padding: 16, backgroundColor: 'deeppink', borderRadius: 8, }, }) export default App
注:
onOuterClick
7vux5j2d4#
经过长时间的搜索,我找到了一个非常好的库,叫做react-native-swipe-down,有MIT许可证。它可以帮助你毫不费力地制作一个滑块<View />。我希望这个图书馆能帮到你。
<View />
import SwipeUpDown from 'react-native-swipe-up-down'; <SwipeUpDown itemMini={<ItemMini />} // Pass props component when collapsed itemFull={<ItemFull />} // Pass props component when show full onShowMini={() => console.log('mini')} onShowFull={() => console.log('full')} onMoveDown={() => console.log('down')} onMoveUp={() => console.log('up')} disablePressToShow={false} // Press item mini to show full style={{ backgroundColor: 'green' }} // style for swipe />
knpiaxh15#
为了达到上述要求,我们可以借助一些大的图书馆1.@gorhom/底层床单
import React, { useState } from 'react' import { SafeAreaView, View, ScrollView, Text, Dimensions, TouchableOpacity, Animated } from 'react-native' const App = () => { const { height, width } = Dimensions.get('window') const SCREEN_HEIGHT = Math.round(height) const SCREEN_WIDTH = Math.round(width) // Animation const startValue = new Animated.Value(Math.round(height + height * 0.3)) const endValue = Math.round(height - height * 0.3) const duration = 1000 const _showBottomView = (key) => { const toValue = key === 'HIDE' ? height : endValue Animated.timing(startValue, { toValue, duration: duration, useNativeDriver: true, }).start() } return ( <SafeAreaView style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.1)' }}> {/* Header */} <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', borderWidth: 1, borderColor: 'black', margin: 5 }}> <Text> Header </Text> </View> <View style={{ flex: 9, borderWidth: 1, borderColor: 'black', margin: 5 }}> <ScrollView style={{ flex: 1 }}> {/* Title View */} <View style={{ height: SCREEN_HEIGHT * 0.1, width: '95%', borderColor: 'black', borderWidth: 1, marginLeft: '2.5%', marginTop: SCREEN_HEIGHT * 0.01, alignItems: 'center', justifyContent: 'center', }}> <Text> Content ONE </Text> </View> <View style={{ height: SCREEN_HEIGHT * 0.5, width: '95%', borderColor: 'black', borderWidth: 1, marginLeft: '2.5%', marginTop: SCREEN_HEIGHT * 0.01, alignItems: 'center', justifyContent: 'center', }}> <Text> Content TWO </Text> </View> <View style={{ height: SCREEN_HEIGHT * 0.2, width: '95%', borderColor: 'black', borderWidth: 1, marginLeft: '2.5%', marginTop: SCREEN_HEIGHT * 0.01, alignItems: 'center', justifyContent: 'center', }}> <TouchableOpacity activeOpacity={0.85} onPress={() => _showBottomView()} style={{ height: SCREEN_HEIGHT * 0.065, width: '75%', borderRadius: 5, borderWidth: 1, borderColor: 'green', alignItems: 'center', justifyContent: 'center', }}> <Text> SHOW BOTTOM VIEW </Text> </TouchableOpacity> </View> <View style={{ height: SCREEN_HEIGHT * 0.3, width: '95%', borderColor: 'black', borderWidth: 1, marginLeft: '2.5%', marginTop: SCREEN_HEIGHT * 0.01, alignItems: 'center', justifyContent: 'center', marginBottom: SCREEN_HEIGHT * 0.01 }}> <Text> ...REST_CONTENT... </Text> </View> </ScrollView> </View> {/* Bottom view */} <Animated.View style={[ { position: 'absolute', height: height * 0.3, width: width, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center', borderTopRightRadius: 23, borderTopLeftRadius: 23, transform: [ { translateY: startValue }, ], }, ]} > <TouchableOpacity activeOpacity={0.85} onPress={() => _showBottomView('HIDE')} style={{ height: SCREEN_HEIGHT * 0.065, width: '75%', borderRadius: 5, borderWidth: 1, borderColor: 'green', alignItems: 'center', justifyContent: 'center', }}> <Text> HIDE BOTTOM VIEW </Text> </TouchableOpacity> </Animated.View> </SafeAreaView> ) } export default App
演示
5条答案
按热度按时间58wvjzkj1#
基本上,你需要把你的视图绝对定位到屏幕的底部,然后你平移它的y值使其等于它的高度。(子视图必须有一个特定的高度,以便知道它移动了多少)
代码:
ltskdhd12#
我知道这有点晚了,但是我想它可能对某些人有用。你应该试试一个叫做
rn-sliding-out-panel
的组件。它工作得非常好。https://github.com/octopitus/rn-sliding-up-panel您甚至可以通过外部按钮打开它:
您可以通过npm安装它:
sudo npm install rn-sliding-out-panel --save
位于您的react-native根目录上。我希望它能对某人有所帮助:D
t1qtbnec3#
我创建了一个可重用的
BottomSheet
组件,它接受任何内容。它看起来是这样的:
下面是
BottomSheet
组件的代码(TypeScript格式):我把这段代码放在一个名为
BottomSheet.tsx
的文件中。BottomSheet
的使用方法如下:注:
onOuterClick
回调函数实现的,这是可选的--如果你不想做任何事情,就不要传递它。7vux5j2d4#
经过长时间的搜索,我找到了一个非常好的库,叫做react-native-swipe-down,有MIT许可证。它可以帮助你毫不费力地制作一个滑块
<View />
。我希望这个图书馆能帮到你。
knpiaxh15#
为了达到上述要求,我们可以借助一些大的图书馆
1.@gorhom/底层床单
但是如果我们想原生地完成它,请找到下面显示的代码,我将尝试证明答案:)
对于一些动画效果,我将从打击地点how-to-create-moving-animations-in-react-native获取参考
演示