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

7 uiscrollview uiview touchesmoved touchesbegan ios

我收到的那一刻touchesBegan,我想要removeFromSuperview触摸的视图和addSuperview新的父视图,然后继续接受触摸.但是我发现有时这不起作用.具体来说,touchesMovedtouchesEnded永远不会被调用.

有没有让这项工作正确的技巧?这用于实现拖放行为,其中视图最初位于滚动视图内.

谢谢.

Jos*_*eld 7

代替:

[transferView removeFromSuperView];
[newParentView addSubview:transferView];
Run Code Online (Sandbox Code Playgroud)

仅限使用:

[newParentView addSubview:transferView];
Run Code Online (Sandbox Code Playgroud)

在文档中声明"视图只能有一个超级视图.如果视图已经有超视图并且该视图不是接收者,则此方法会在使接收者成为新的超级视图之前删除先前的超视图."

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


Aar*_*man 0

您需要在超级视图中而不是在要切换的视图中处理触摸。这将允许您切换视图而不会丢失触摸事件。但是,当您执行此操作时,您必须自己测试触摸是否发生在您想要切换的特定子视图中。这可以通过多种方式完成,但这里有一些可以帮助您入门的方法:

将矩形/点转换为另一个视图:

[view convertRect:rect toView:subview];
[view convertPoint:point toView:subview];
Run Code Online (Sandbox Code Playgroud)

以下是测试该点是否位于视图中的一些方法:

[subView hitTest:point withEvent:nil];
CGRectContainsPoint(subview.frame, point); //No point conversion needed
[subView pointInside:point withEvent:nil];
Run Code Online (Sandbox Code Playgroud)

一般来说,最好使用 UIGestureRecognizers。例如,如果您使用 UIPanGestureRecognizer,您将创建一个手势识别器可以调用的方法,并在该方法中完成您的工作。例如:

- (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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后初始化识别器,将其分配给目标(通常是自身)并添加它:

[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewPanned:)]];
Run Code Online (Sandbox Code Playgroud)

现在 self(这将是管理其子视图的超级视图)将响应平移动作。