我收到的那一刻touchesBegan
,我想要removeFromSuperview
被触摸的视图和addSuperview
新的父视图,然后继续接收触摸。但是我发现有时这不起作用。具体来说,touchesMoved
永远touchesEnded
不会被调用。
有没有使这项工作正常工作的技巧?这是为了实现拖放行为,其中视图最初位于滚动视图内。
谢谢。
我收到的那一刻touchesBegan
,我想要removeFromSuperview
被触摸的视图和addSuperview
新的父视图,然后继续接收触摸。但是我发现有时这不起作用。具体来说,touchesMoved
永远touchesEnded
不会被调用。
有没有使这项工作正常工作的技巧?这是为了实现拖放行为,其中视图最初位于滚动视图内。
谢谢。
代替:
[transferView removeFromSuperView];
[newParentView addSubview:transferView];
仅使用:
[newParentView addSubview:transferView];
文档指出: “视图只能有一个超级视图。如果视图已经有一个超级视图并且该视图不是接收者,则此方法会在使接收者成为其新的超级视图之前删除先前的超级视图。”
因此不需要使用 removeFromSuperView,因为它是由 addSubview 处理的。我注意到 removeFromSuperView 会在不调用 touchesEnded 的情况下结束任何当前的触摸。如果您只使用 addSubview,触摸不会中断。
您需要在超级视图中处理您的触摸,而不是在您想要切换的视图中。这将允许您在不丢失触摸事件的情况下切换视图。但是,当您执行此操作时,您必须测试自己是否在要切换的特定子视图中发生触摸。这可以通过多种方式完成,但这里有一些方法可以帮助您入门:
将 Rects/Point 转换为另一个视图:
[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:)]];
现在 self (这将是管理它的子视图的超级视图)将响应平移动作。