React Native:刷卡,文本输入,动画和手势响应器

这周,我对React Native进行了第一次“认真”的尝试,发现一些令人惊讶的令人讨厌的东西,而文献记载却很少。 我希望这对其他人(或有更好解决方案的人)有所帮助。

让我们从刷卡开始

作为非iOS开发人员,我实际上不知道该模式的正确名称,Apple却喜欢将其命名为UITableViewRowAction。 不幸的是,React Native没有包含如此出色的现成解决方案。

由于缺少正式的解决方案,我跳到coach.js上,找到了希望有人已经编写的组件。 我选择与react-native-swipeout一起使用。 这是一个非常不错的图书馆简单图书馆,我或多或少开箱即用。 (注意:NPM版本已经严重过时,我最初只是使用NPM,但没有,只是使用了仓库)

从那以后,我就将它分叉了,用React Native LayoutAnimations替换了动画以减少依赖性(并且我想它会更高效),并且使手势处理对用户来说更加直观。

布局动画

LayoutAnimations是一个非常酷的库,它使您可以轻松地创建动画,并且或多或少都有文档记录。 您可以像这样创建漂亮的动画:

  LayoutAnimation.easeInEaseOut(); 
this.setState({elementHeight:1}); //确保它不为0!
//设置元素的高度取决于this.state.elementHeight,我们都很好

但是请稍等,如果我将elementHeight设置为0会怎样? 看来React决定进行优化并完全删除元素而没有任何动画! 但是,如果我想完全隐藏该元素怎么办? hacky修复实际上还不错。 (您可以在GIF中看到它的实际效果)。

  LayoutAnimation.easeInEaseOut(()=> { 
//完成动画后,将高度设置为0
this.setState({elementHeight:0});
});
this.setState({elementHeight:1});

只需将动画设置为1px,然后在动画结束后将高度设置为0,使其消失即可。 这样,动画仍然可以正常工作,最后元素仍然可以完全消失。

TextInputs +滑动和手势响应器!

现在,我认为这是困难的部分。 该应用程序的部分需求当然是即使您在TextInput顶部开始滑动,也能够滑动出删除按钮。 默认情况下,如果点按了TextInput,它将“窃取”并“锁定”该手势至其自身,拒绝将其放弃给其他任何人。 如果您要在Swipeout中嵌套TextInput并期望Swipeout处理滑动,则这是个坏消息。 根本原因是什么? 这条线在这里。 那条线到底是做什么的? 好吧,这变得有些困难。

React Native中的大多数手势都建立在Gesture Responder系统之上。 当手势开始时,因此当您的手指第一次与屏幕接触时,它将找到“最深”元素,并询问是否要处理手势(使用onStartShouldSetResponder)。 TextInput总是要求处理输入(禁用时除外),就在用户第一次进行联系时(不知道此点击是否会变成滑动)。 现在,当用户开始拖动手指,并且手势响应器现在意识到这是“移动” /滑动时,它将再次询问元素是否要处理移动手势。 现在的问题是Swipeout想要处理移动手势,但是当Swipeout要求处理它时,手势响应器会询问TextInput(通过onResponderTerminationRequest)是否可以放弃对手势的控制。 由于某种原因,TextInput被编码为始终拒绝请求,因此我的Swipeout将永远无法处理TextInput内的手势。 手势响应器文档中的生命周期段落在手势操作中如何调用不同功能方面也非常全面。 同样的想法也适用于PanResponder(高级手势响应系统),如果您使用PanResponder,请参考GestureResponder的生命周期,因为它的本质是相同的。

现在我尝试的是在“ Capture”舞台上偷走手势。 当首次发生手势时,手势响应器将首先从根元素开始,并询问向下的每个元素是否要“捕获”该手势,不再允许子元素对此事件做出响应。 当然,问题很明显,如果您尽早捕获它,那么如果用户实际打算点击TextInput来输入文本,则子TextInput将永远不会获得实际的点击事件。

最后,我要做的是(这绝对是糟糕的)扩展TextInput,覆盖_renderIOS函数,以便将rejectResponderTermination设置为false,然后使用该扩展组件。 这是超级肮脏和次优的,但是它很快解决了一个非常讨厌的问题。 不幸的是,TextInput似乎不够灵活,无法以任何其他方式覆盖该功能。

事实证明这比我原先打算的要长一些。 如果他们正在使用PanResponder,GestureResponder,LayoutAnimation或Swipeouts + TextInputs,我希望这可以节省一些时间。 如果您有任何反馈或建议,请在下面留言!

如果这对您有帮助,请在下面给它一个!!