iOS:在发生触摸时转移UIView的所有权?

iOS:在发生触摸时转移UIView的所有权?,ios,uiview,uiscrollview,touchesbegan,touchesmoved,Ios,Uiview,Uiscrollview,Touchesbegan,Touchesmoved,当我收到触摸开始时,我想从SuperView删除被触摸的视图,并将SuperView添加到新的父视图,然后继续接收触摸。然而,我发现有时这并不奏效。具体来说,touchesMoved和touchesend从未被调用 有没有办法让它正常工作?这用于实现拖放行为,其中视图最初位于滚动视图中 谢谢。您需要在superview中处理您的触摸,而不是在您想要关闭的视图中。这将允许您在不丢失触摸事件的情况下切换视图。但是,当您执行此操作时,您必须测试自己是否在要关闭的特定子视图中发生了触摸。这可以通过多种方

当我收到
触摸开始时
,我想
从SuperView
删除被触摸的视图,并
将SuperView
添加到新的父视图,然后继续接收触摸。然而,我发现有时这并不奏效。具体来说,
touchesMoved
touchesend
从未被调用

有没有办法让它正常工作?这用于实现拖放行为,其中视图最初位于滚动视图中


谢谢。

您需要在superview中处理您的触摸,而不是在您想要关闭的视图中。这将允许您在不丢失触摸事件的情况下切换视图。但是,当您执行此操作时,您必须测试自己是否在要关闭的特定子视图中发生了触摸。这可以通过多种方式完成,但以下是一些让您开始的方法:

将矩形/点转换为其他视图:

[view convertRect:rect toView:subview];
[view convertPoint:point toView:subview];
以下是一些测试点是否位于视图中的方法:

[subView hitTest:point withEvent:nil];
CGRectContainsPoint(subview.frame, point); //No point conversion needed
[subView pointInside:point withEvent:nil];
一般来说,最好使用UIgestureRecognitors。例如,如果您使用的是UIPangestureRecognitor,您将创建一个手势识别器可以调用的方法,并在该方法中执行您的工作。例如:

- (void) viewPanned:(UIPanGestureRecognizer *)pan{
    if (pan.state == UIGestureRecognizerStateBegan){
        CGRect rect = subView.frame;
        newView = [[UIView alloc] initWithFrame:rect];
        [subView removeFromSuperview];
        [self addSubview:newView];
    } else if (pan.state == UIGestureRecognizerStateChanged){
        CGPoint point = [pan locationInView:self];
        newView.center = point;
    } else {
        //Do cleanup or final view placement
    }
}
然后初始化识别器,将其分配给目标(通常为自身)并添加:

[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewPanned:)]];

现在,self(管理其子视图的superview)将响应平移运动。

而不是:

[transferView removeFromSuperView];
[newParentView addSubview:transferView];
[newParentView addSubview:transferView];
仅限使用:

[transferView removeFromSuperView];
[newParentView addSubview:transferView];
[newParentView addSubview:transferView];
状态:“视图只能有一个superview。如果视图已经有一个superview,而该视图不是接收器,则此方法将在接收器成为新superview之前删除以前的superview。”


因此,不需要使用removeFromSuperView,因为它由addSubview处理。我注意到removeFromSuperView在不调用touchesEnded的情况下结束任何当前触摸。如果只使用addSubview,则不会中断触摸。

不确定为什么会这样。你能帮我寄密码吗?顺便说一句,是什么阻止你使用UIGestureRecognitor?几乎在我考虑过使用Touch的所有情况下,我都发现现有的UIgestureRecognitor或子类化UIgestureRecognitor效果更好(我可以重用它)。如果您使用的是库存UIPangestureRecognitor,
TouchesBegind
不应该出现在代码中。您应该像这样设置一些目标方法:
-(void)viewPanned:(uipangestureerecognizer)pan
。初始化识别器时,设置其目标:
[[UIPangestureRecognitizer alloc]initWithTarget:self action:@selector(viewPanned:)]
。该方法将被重复调用,您可以检查状态并执行适当的操作:
If(pan.state==uigestureRecognitizerStateStarted){……}
If(pan.state==uigestureRecognitizerStateChanged{……}
等…我扩展了我的答案以反映这一点。我注意到您正在删除视图并创建另一个视图以添加到目标。我肯定会发现,当我从superview中删除原始视图时,它将停止接收触摸,即使我随后立即将其重新添加到另一个视图。这应该是可接受的答案,因为它不是必需的需要管理superview中的拖动以实现OP的目标。只需从superview中删除removeFromSuperView即可。谢谢walapu。回答得好,这非常有用!