如何在React Native中创建拖放动作?

26
假设我有两个视图,A和B。我想在触摸视图A时触发'dragAndDropStart'事件,然后启用从A到B的拖放... 在整个过程中向用户显示反馈(例如,在视图A和用户的手指之间显示一条线)。当释放拖动手势时,我想在视图B上触发另一个'dragAndDropEnd'事件。
touchStart和touchEnd处理程序太过受限,因为它们似乎不允许将手势从一个视图移交给另一个视图。它们也似乎不能启用中间的“拖动”状态。
React Native文档对使用手势处理程序的说明有点晦涩,我还没有看到任何演示它们使用的示例。
有什么想法吗?

1
我不知道你是否专门为这篇文章制作了这个图表,但它非常棒。 - Joshua Pinter
谢谢Josh,图表是我更喜欢的东西,甚至比代码还要多! - Pete Thorne
你在身边会很有用! - Joshua Pinter
2个回答

16
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>
            );
        }
    }
}

来源 https://moduscreate.com/blog/drag-and-drop-react-native/

https://github.com/crysfel/DragAndDrop


这看起来非常有前途,我在尝试将代码更新到最新的React Native版本时出现了错误,但一旦我可以再次测试,我会确认这个解决方案,谢谢。 - Pete Thorne
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Pete Thorne
有人能够大致解释一下 <View {...this.abc}/> 的含义吗? - Anand Undavia
请阅读 https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes,这里也不是提问的正确地方。 - Harry Moreno

-8

如果您的视图矩形相交,则必须将当前视图矩形与其他视图矩形进行比较,如果它们在某一点相交,则返回 true,然后您会收到通知 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 ");
            

        }
      
        
     
       
    }
}
  


是的,请尝试一下,如果您需要Xcode项目示例,我也会为您提供链接。 - Abhay Singh Naurang
2
这不是 React Native。 - Magenta Nova

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接