親PanResponder
と子TouchableOpacityがあります。 TouchableOpacity
がクリックを取得するため、PanResponder
はクリックに応答しません。私はこのガイドに従ってみましたが成功しませんでした: http://browniefed.com/blog/react-native-maintain-touchable-items-with-a-parent-panresponder/
これは私のコードです:
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
onMoveShouldSetResponderCapture: () => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
return gestureState.dx != 0 && gestureState.dy != 0;
},
onPanResponderGrant: (evt, gestureState) => {
let isFirst = gestureState.y0 > 164 ? false : true;
this.setState({animObj: isFirst, isUsingCurtain: true});
},
onPanResponderMove: (evt, gestureState) => {
//let Y = this.state.animObj ? gestureState.moveY - this.state.currentHeaderHeight : gestureState.moveY - this.state.currentHeaderHeight ;// - this.state.currentHeaderHeight;
let Y = gestureState.moveY - this.state.currentHeaderHeight + 20
if (Y < 0) {
return false
}
this.state.animCurtain.setValue(Y);
gestureState.moveY > height / 2 ? this.setState({curtainOnMiddle: true}) : this.setState({curtainOnMiddle: false})
},
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
if (((height / 2) > gestureState.moveY)) {//slide back up1
this._CurtainAnimation(0, false);
} else {//slide to bottom
let val = height - calcSize(180);
this._CurtainAnimation(val, true);
}
},
onPanResponderTerminate: (evt, gestureState) => {
},
onPanResponderStart: (e, gestureState) => {
},
});
これが私の見解です:
<Animated.View
style={[styles.bottomHPHeader, TopArroOpacity ? {opacity: TopArroOpacity} : ""]} {...this._panResponder.panHandlers}>
<TouchableOpacity onPress={() => this._animateAutoCurtain()}>
{this.state.curtainOnMiddle ?
<AIIcon image={require('../../../../assets/images/homepage/close_drawer_arrow.png')}
boxSize={30}/>
: <AIIcon image={require('../../../../assets/images/homepage/open_drawer_arrow.png')}
boxSize={30}/>}
</TouchableOpacity></Animated.View>
ありがとうございました
私の場合の解決策はonMoveShouldSetPanResponder
を変更することでした
onMoveShouldSetPanResponder: (evt, gestureState) => {
//return true if user is swiping, return false if it's a single click
return !(gestureState.dx === 0 && gestureState.dy === 0)
}
パーフェクト!感度が良かったので調整しました。
onMoveShouldSetPanResponder: (evt, gestureState) => {
const { dx, dy } = gestureState
return dx > 2 || dx < -2 || dy > 2 || dy < -2
}
私はまったく同じ問題を抱えていました。ソリューションは、上記のソリューションを組み合わせたものです。 onMoveShouldSetPanResponderとonMoveShouldSetPanResponderCaptureの両方に条件を追加する必要がありました。これが私がしたことです。
onMoveShouldSetPanResponder: (_, gestureState) => {
const { dx, dy } = gestureState
return (dx > 2 || dx < -2 || dy > 2 || dy < -2)
},
onMoveShouldSetPanResponderCapture: (_, gestureState) => {
const { dx, dy } = gestureState
return (dx > 2 || dx < -2 || dy > 2 || dy < -2)
},
this.panResponder = PanResponder.create({
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
});
少し異なった状況がすべての人にとってうまくいくようです...これは私のために働いたPanResponder.create
プロパティの組み合わせです(私は子要素へのタップを許可しようとしましたが、PanResponderで動きをキャプチャしました:
onStartShouldSetPanResponder: ( e, state ) => false,
onStartShouldSetPanResponderCapture: ( e, state ) => false,
onMoveShouldSetPanResponder: ( e, state ) => true,
onMoveShouldSetPanResponderCapture: ( e, state ) => true,
これが他の誰かの役に立つことを願っていますが、どういうわけか私を悩ませることはありません!
Android向けの私のソリューション。他のすべてはfalse
を返します
onMoveShouldSetPanResponder: (evt, { dx, dy }) => dx !== 0 || dy !== 0,
私は同様の問題に気付きましたが、ボタンを絶対位置に配置し、それをパンビューの上に保つことでパンビューを内部に含むコンテナービューを作成することが役に立ちました。それはすべての人に合うことはできませんでしたが、ボタンが完全に配置できる場合(私のように)は機能します。
パンビューとボタンを持つコンポーネントのサンプルコードを次に示します。
import React, { Component } from "react";
import {
Animated,
View,
Text,
StyleSheet,
PanResponder,
TouchableOpacity
} from "react-native";
export class ToolRuler extends Component {
constructor(props) {
super(props);
this.state = {
moveX: 0,
moveY: 0
};
}
componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
onMoveShouldSetResponderCapture: () => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
// anything
},
onPanResponderMove: (evt, gestureState) => {
this.setState({
moveX: gestureState.moveX,
moveY: gestureState.moveY
});
},
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
this.setState({
moveX: gestureState.moveX,
moveY: gestureState.moveY
});
},
onPanResponderTerminate: (evt, gestureState) => {},
onPanResponderStart: (e, gestureState) => {}
});
}
render() {
return (
<View
style={{
flex: 1,
position: "relative",
alignItems: "center",
justifyContent: "center"
}}
>
<Animated.View
{...this._panResponder.panHandlers}
style={{ flex: 1, width: "100%", backgroundColor: "#ccc" }}
>
<Text style={{ marginTop: 200, textAlign: "center" }}>
x: {this.state.moveX}, y: {this.state.moveY}
</Text>
</Animated.View>
<TouchableOpacity
style={{
position: "absolute"
}}
onPress={() => alert("I am tapped!")}
>
<Text>Click Me</Text>
</TouchableOpacity>
</View>
);
}
}