3

我有了这个代码的设备一个TouchableOpacity或TouchableHighlight点击:如何使在支持3D触摸(力触摸)

<View {...this.panGesture.panHandlers}> 
    <Animated.View> 

     <View style={{ position: 'absolute' }}> 
      <TouchableHighlight onPress={() => {console.log('hello')}> 
      </TouchableHighlight> 
     </View> 

    </Animated.View> 
</View> 

,我不能为我的爱让onPress工作对于iPhone 6s及以上版本,启用3D触控时。

我试过大多数解决方案建议here,但没有运气。

我会很感激任何帮助!

回答

0

好了之后,摆弄了很多这个,我意识到解决方案是部分jevakallio说,但我不能再使用3D触摸时,使用Touchables,所以我必须手动重现他们的行为。

我的代码现在看起来像这样: 的孩子代码:

let touchable; 

if (View.forceTouchAvailable === false) { // if 3d touch is disabled 
    // just use a Touchable and all should be fine. 
    touchable = (<TouchableHighlight 
     onPress={() => {console.log('hello world');} 
     style={this.props.style} 
     underlayColor={this.props.highlightBgColor} 
    > 
     {this.props.children} 
    </TouchableHighlight>); 
} else { // Otherwise if 3D touch is enabled 
    // we'll have to use a child view WITH a PanResponder 
    touchable = (<View 
     style={[this.props.style, { 
     backgroundColor: this.state.panViewIsTapped ? 
      this.props.highlightBgColor 
      : 
      bgColor, 
     }]} 
     {...this.panResponderChild.panHandlers} 
    > 
     {this.props.children} 
    </View>); 
} 

return (<View {...this.panResponderParent.panHandlers}> 
    <Animated.View> 

     <View style={{ position: 'absolute' }}> 
      {touchable} 
     </View> 

    </Animated.View> 
</View>); 

孩子锅响应代码(this.panResponderChild):

this.panResponderChild = PanResponder.create({ 

     // true because we want tapping on this to set it as the responder 
     onStartShouldSetPanResponder:() => true, 

     // true because we want this to capture the responder lock from it's parent on start 
     onStartShouldSetPanResponderCapture:() => true, 

     // when the pan responder lock is terminated, set the pan view as NOT tapped 
     onPanResponderTerminate:() => { 
      this.setState({ panViewIsTapped: false }); 
     }, 

     // true so that the parent can grab our responder lock if he wan'ts to. 
     onPanResponderTerminationRequest:() => true, 

     // false because we DON'T want this btn capturing the resp lock from it's parent on move 
     onMoveShouldSetPanResponderCapture:() => false, 

     // false because we DON'T want moving the finger on this to set it as the responder 
     onMoveShouldSetPanResponder:() => false, 

     onPanResponderGrant:() => { 
      this.setState({ panViewIsTapped: true }); 
     }, 

     onPanResponderRelease:() => { 
      this.setState({ panViewIsTapped: false }); 
      console.log('hello world'); 
     }, 
}) 

锅响应代码(this.panResponderParent):

this.panResponderParent = PanResponder.create({ 

     // true because we want tapping on the cal, to set it as a responder 
     onStartShouldSetPanResponder:() => true, 

     // false because we DON'T want to grab the responder lock from our children on start 
     onStartShouldSetPanResponderCapture:() => false, 

     /* 
     onMoveShouldSetPanResponderCapture: 
     false because we don't want to accidentally grab the responder lock from 
     our children on movement. 
      That's because sometimes even a small tap contains movement, 
      and thus a big percentage of taps will not work. 
      Keeping that flag false does not nessecarily mean that our children will 
     always capture the responder lock on movement, (they can if they want), 
     we're just not strict enough to grab it from them. 
     */ 
     onMoveShouldSetPanResponderCapture:() => false, 

     /* 
     onMoveShouldSetPanResponder: 
     We DO want moving the finter on the cal, to set it as a responder, 
     BUT, we don't always want moving the finger on an appointment setting this parent 
     as the responder. 

     Logic: 
     So, when the dx AND dy of the pan are 0, we return false, because we don't 
     want to grab the responder from our appointment children. 

     For anything other than that we just allow this parent to become the responder. 

     (dx, dy: accumulated distance of the gesture since the touch started) 
     */ 
     onMoveShouldSetPanResponder: (e, gestureState) => 
     !(gestureState.dx === 0 || gestureState.dy === 0), 


    }); 
2

我已经能够确保父PanResponder抢不上招响应要解决这一具体问题,直到触摸实际上已经从原点移动:

PanResponder.create({ 

    //... other responder callbacks 

    onMoveShouldSetPanResponder(e, gestureState) { 
    if (gestureState.dx === 0 || gestureState.dy === 0) { 
     return false; 
    } 
    return true; 
    } 
}); 

这是早在身边React Native 0.10天,从此没有尝试过。希望能帮助到你!

+0

这似乎并没有解决我的问题。当然,我需要在具有3D触摸的设备上进行测试,但在非3D触摸设备上,我可以看到,'onMoveShouldSetPanResponder'根本不会被调用,因为点击'TouchableHighlight'时,因此没有必要在其中添加代码。 ! 只有当我在屏幕上拖动/移动手指而不是单击时,才会调用此函数。 任何想法? – SudoPlz

+0

此变通办法解决了仅在3d设备上触发的问题。我不能保证它会起作用,但我认为你应该尝试一下! – jevakallio