如何在React Native中重建iOS选择器动画

4
有没有在React Native中完全使用Java Script重建iOS picker组件的方法?我不需要常见的picker,而是一个普通的滚动视图,具有与iOS picker类似的淡出效果。

enter image description here

编辑 - 我认为我没有完全解释清楚我的初始答案。这就是为什么我在这里补充它的原因:

我想建立一个占据整个屏幕的滚动视图。它不应该给用户选择某个项目的可能性,就像iOS Picker一样。尽管如此,它应该是一个“普通”的滚动视图,向用户展示一些信息,例如不同的聊天、任务、新闻等。

与React Native的常规滚动视图唯一的区别应该是顶部的淡出效果:当用户向上滚动内容时,它不应该只在其顶部边缘离开屏幕,而应该使用iOS Picker的淡出效果(见图片)。

这种淡出效果由两个部分组成:首先,它随着y坐标的减小提高了内容的透明度。此外,这个内容似乎进入了第三维。

我的问题是,我没有看到在React Native中实现内容三维效果的方法。我必须补充说明的是,我的滚动视图中的内容不是由小型的、大小相等的项目(例如文本“项目1”、“项目2”、“项目3”等)组成,而是由不同大小的大型项目组成,例如图像或整个文本框。

2个回答

0

你可以使用这个 NPM 模块 来得到你想要的东西。这个模块在 Android 和 iOS 上都可以工作。不要重复造轮子 :)

编辑:现在我明白你想要什么了。你可以试试我为你准备的这个小吃:

https://snack.expo.io/r1qnxSt9m

当然你需要改进它,但这是一个开始。


@Paul,你可以下载我之前提到的NPM模块的源代码。看一下它是如何实现这种效果的。我认为它使用了react-native-animatable(https://github.com/oblador/react-native-animatable)。 - shimatai
@shimatai 谢谢你提供的想法!不幸的是,react-native-simple-picker使用React Native的Picker组件,而该组件又使用iOS的本地选择器组件。这意味着,所需的淡出效果并未直接包含在react-native-simple-picker中。你有没有其他想法来实现React Native中的所需效果?我会看看react-native-animatable... - Paul
@Paul 如果你正在使用 ListView 组件,在 renderRow 方法中,你可以为当前项应用自定义样式。如果当前项不是选定的项,则可以应用淡化样式。renderRow 方法具有 rowID 属性,让你知道数组中的哪个位置。 - shimatai
@shimatai 非常感谢您的帮助。我认为我没有准确地解释我的请求。这就是为什么我更新了我的初始问题。 - Paul
谢谢这个小吃。不幸的是,我正在寻找一个 "淡出" 效果的内容,它 "不由小而等大小的项目组成(例如文本 '项目 1'、'项目 2'、'项目 3'...),而是由不同大小的大型项目组成,例如图像或整个文本框"(请参见问题中的编辑)。对于这样的内容,您的方法不适用。但我将使用您的小吃作为自己解决方案的灵感。 - Paul
显示剩余2条评论

0
你可以使用动画 API 实现所需效果。其思想是为列表中的项设置不同的输入范围。然后将不透明度钩子连接到 ScrollView(或任何列表组件)的滚动值。我已经简化了代码,但应足以演示这个想法。
下面的示例仅演示不透明度效果,但您可以轻松添加平移效果,以获得您要查找的确切动画。

const data = []; // array that contains the text
const items = [];
for (let i = 0; i < data.length; ++i) {
  const distanceFromViewCenter = Math.abs(i * ITEM_HEIGHT);
  const inputRange = [
    -distanceFromViewCenter - 2 * ITEM_HEIGHT,
    -distanceFromViewCenter - ITEM_HEIGHT,
    -distanceFromViewCenter, // Middle of picker            
    -distanceFromViewCenter + ITEM_HEIGHT,
    -distanceFromViewCenter + 2 * ITEM_HEIGHT,
  ];
  items.push(
    <Animated.View
      style={{
        opacity: this._scrollValue.interpolate({
          inputRange,
          outputRange: [0.0, 0.3, 1.0, 0.3, 0.0],
        }),
      }}
    >
      <Text style={{ height: ITEM_HEIGHT }}>{data[i]}</Text>
    </Animated.View>
  )
}

<ScrollView
  onScroll={Animated.event(
    [{ nativeEvent: { contentOffset: { y: this._scrollValue } } }],
    { useNativeDriver: true }
  )}
>
  {items}
</ScrollView>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接