如何在 React Native 中创建拖放操作?
How can I create a drag and drop action in React native?
假设我有两个视图,A 和 B。我希望能够在触摸视图 A 时触发 'dragAndDropStart' 事件,然后启用从 A 到 B 的拖放...显示反馈始终向用户显示(即显示视图 A 和用户手指之间出现的一条线)。放下时(释放拖动手势)我想触发另一个 'dragAndDropEnd' 事件,这次是在视图 B 上。
touchStart 和 touchEnd 处理程序过于有限,因为它们似乎不允许将手势从一个视图切换到另一个视图。他们似乎也没有启用中间 'drag' 状态。
关于使用手势处理程序的 React 本机文档有点含糊不清,我还没有看到任何演示其用法的示例。
有什么想法吗?
您必须将当前的视图矩形与其他视图矩形进行对比,如果您的视图矩形之一在某个点彼此相交,它将 return 为真,然后您会收到通知,即 A 视图已拖动到 B 视图这是我的示例代码,可能会对您有所帮助。
-(void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer{
// your current View touch location suppose View A
CGPoint touchLocation = [panGestureRecognizer locationInView:self.contentView];
CGRect movingAViewRect = CGRectMake(touchLocation.x, touchLocation.y, self.aView.width, self.aView.height);
// NSLog(@"Point not Matched first => %@ and second => %@",NSStringFromCGPoint(touchLocation),NSStringFromCGPoint(self.bView.frame.origins));
self.aView.center = touchLocation;
if(panGestureRecognizer.state == UIGestureRecognizerStateEnded)
{
//All fingers are lifted.
if(CGRectIntersectsRect(movingAViewRect,self.bView.frame)){
NSLog(@"Point Matched first => %@ and second => %@",NSStringFromCGRect(movingAViewRect),NSStringFromCGRect (self.bView.frame ));
// and here you can perform some action for this
}else{
NSLog(@"aView is not drag on bView please drag aView to bView ");
}
}
}
export default class Viewport extends Component{
constructor(props){
super(props);
this.state = {
showDraggable : true,
dropZoneValues : null,
pan : new Animated.ValueXY()
};
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder : () => true,
onPanResponderMove : Animated.event([null,{
dx : this.state.pan.x,
dy : this.state.pan.y
}]),
onPanResponderRelease : (e, gesture) => {
if(this.isDropZone(gesture)){
this.setState({
showDraggable : false
});
}else{
Animated.spring(
this.state.pan,
{toValue:{x:0,y:0}}
).start();
}
}
});
}
isDropZone(gesture){
var dz = this.state.dropZoneValues;
return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;
}
setDropZoneValues(event){
this.setState({
dropZoneValues : event.nativeEvent.layout
});
}
render(){
return (
<View style={styles.mainContainer}>
<View
onLayout={this.setDropZoneValues.bind(this)}
style={styles.dropZone}>
<Text style={styles.text}>Drop me here!</Text>
</View>
{this.renderDraggable()}
</View>
);
}
renderDraggable(){
if(this.state.showDraggable){
return (
<View style={styles.draggableContainer}>
<Animated.View
{...this.panResponder.panHandlers}
style={[this.state.pan.getLayout(), styles.circle]}>
<Text style={styles.text}>Drag me!</Text>
</Animated.View>
</View>
);
}
}
}
来源http://moduscreate.com/animated_drag_and_drop_with_react_native/
假设我有两个视图,A 和 B。我希望能够在触摸视图 A 时触发 'dragAndDropStart' 事件,然后启用从 A 到 B 的拖放...显示反馈始终向用户显示(即显示视图 A 和用户手指之间出现的一条线)。放下时(释放拖动手势)我想触发另一个 'dragAndDropEnd' 事件,这次是在视图 B 上。
touchStart 和 touchEnd 处理程序过于有限,因为它们似乎不允许将手势从一个视图切换到另一个视图。他们似乎也没有启用中间 'drag' 状态。
关于使用手势处理程序的 React 本机文档有点含糊不清,我还没有看到任何演示其用法的示例。
有什么想法吗?
您必须将当前的视图矩形与其他视图矩形进行对比,如果您的视图矩形之一在某个点彼此相交,它将 return 为真,然后您会收到通知,即 A 视图已拖动到 B 视图这是我的示例代码,可能会对您有所帮助。
-(void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer{
// your current View touch location suppose View A
CGPoint touchLocation = [panGestureRecognizer locationInView:self.contentView];
CGRect movingAViewRect = CGRectMake(touchLocation.x, touchLocation.y, self.aView.width, self.aView.height);
// NSLog(@"Point not Matched first => %@ and second => %@",NSStringFromCGPoint(touchLocation),NSStringFromCGPoint(self.bView.frame.origins));
self.aView.center = touchLocation;
if(panGestureRecognizer.state == UIGestureRecognizerStateEnded)
{
//All fingers are lifted.
if(CGRectIntersectsRect(movingAViewRect,self.bView.frame)){
NSLog(@"Point Matched first => %@ and second => %@",NSStringFromCGRect(movingAViewRect),NSStringFromCGRect (self.bView.frame ));
// and here you can perform some action for this
}else{
NSLog(@"aView is not drag on bView please drag aView to bView ");
}
}
}
export default class Viewport extends Component{
constructor(props){
super(props);
this.state = {
showDraggable : true,
dropZoneValues : null,
pan : new Animated.ValueXY()
};
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder : () => true,
onPanResponderMove : Animated.event([null,{
dx : this.state.pan.x,
dy : this.state.pan.y
}]),
onPanResponderRelease : (e, gesture) => {
if(this.isDropZone(gesture)){
this.setState({
showDraggable : false
});
}else{
Animated.spring(
this.state.pan,
{toValue:{x:0,y:0}}
).start();
}
}
});
}
isDropZone(gesture){
var dz = this.state.dropZoneValues;
return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;
}
setDropZoneValues(event){
this.setState({
dropZoneValues : event.nativeEvent.layout
});
}
render(){
return (
<View style={styles.mainContainer}>
<View
onLayout={this.setDropZoneValues.bind(this)}
style={styles.dropZone}>
<Text style={styles.text}>Drop me here!</Text>
</View>
{this.renderDraggable()}
</View>
);
}
renderDraggable(){
if(this.state.showDraggable){
return (
<View style={styles.draggableContainer}>
<Animated.View
{...this.panResponder.panHandlers}
style={[this.state.pan.getLayout(), styles.circle]}>
<Text style={styles.text}>Drag me!</Text>
</Animated.View>
</View>
);
}
}
}
来源http://moduscreate.com/animated_drag_and_drop_with_react_native/