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