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

问题描述 投票:7回答:2

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

是否有使这项工作正常进行的技巧?这是为了实现拖放行为,该视图最初位于滚动视图内。

谢谢。

ios uiview uiscrollview touchesbegan touchesmoved
2个回答
7
投票

代替:

[transferView removeFromSuperView];
[newParentView addSubview:transferView];

仅用于:

[newParentView addSubview:transferView];

documentation声明:“视图只能具有一个超级视图。如果视图已经具有一个超级视图,并且该视图不是接收者,则此方法在使接收者成为其新的超级视图之前,先删除先前的超级视图。”

因此,无需使用removeFromSuperView,因为它由addSubview处理。我注意到removeFromSuperView会结束当前的所有触摸,而不会调用touchesEnded。如果仅使用addSubview,则触摸不会中断。


0
投票

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

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

[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];

通常,最好使用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
    }
}

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.