跨多个子视图传递 UITouch * 的正确方法是啥?

Posted

技术标签:

【中文标题】跨多个子视图传递 UITouch * 的正确方法是啥?【英文标题】:What is the proper way of passing UITouch * across multiple subviews?跨多个子视图传递 UITouch * 的正确方法是什么? 【发布时间】:2013-07-26 07:51:30 【问题描述】:

我有一个包含多个子视图的自定义视图。它们都是屏幕上的圆圈,有点像三个不同半径的***在彼此之上。我试图让他们正确接收 UITouch * 事件以使他们用手指旋转。由于屏幕上的形状实际上是正方形,当一个较大的翻转并且它的可触摸区域进入上面的圆形框架时,它就变得不可触摸了。

因此,我在其他子视图之上创建了另一个子视图,它将计算触摸点到中心的距离并相应地分配触摸事件。我可以想到几种方法,但我想知道处理这种情况的最优雅、最正确的方法是什么。

这是我到目前为止所做的:我的自定义视图有一个委托,并且该委托被分配给我的主 viewController。我的自定义视图中有三个协议方法,分别用于三个***。我正在根据 UITouch 的点传递触摸和事件,但我不确定我应该如何实际将这些数据发送到应该接收它的视图。它们都是自定义 UIControl 对象,它们都通过-beginTrackingWithTouch:withEvent: 处理触摸。由于这是一个私有方法,我无法从我的 viewController 访问它。我应该公开这个方法并从 viewController 访问它,还是有更正确的处理方法?

编辑:添加代码:

这就是我在自定义 UIView 对象中分配触摸的方式。计算工作正常。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    //Distribute the touches according to the touch location.
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];

    //calculations for the circles.
    CGFloat xDistance = (point.x - BIGGEST_CIRCLE_RADIUS);
    CGFloat yDistance = (point.y - BIGGEST_CIRCLE_RADIUS);
    CGFloat distance = sqrtf((xDistance*xDistance) + (yDistance*yDistance));

    //Check to see if the point is in one of the circles, starting from the innermost circle.
    if (distance <= SMALLEST_CIRCLE_RADIUS) 
        [self.delegate smallestCircleReceivedTouch:touch withEvent:event];
     else if (distance < MIDDLE_CIRCLE_RADIUS) 
        [self.delegate middleCircleReceivedTouch:touch withEvent:event];
     else if (distance <= BIGGEST_CIRCLE_RADIUS) 
        [self.delegate biggestCircleReceivedTouch:touch withEvent:event];
     else 
        return;
    

delegate 是 viewController,圆圈是自定义 UIControls。他们像这样处理触摸:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event 

    CGPoint touchPoint = [touch locationInView:self];

    ....

    return YES;

这些本身工作正常,但我不确定我应该如何将委托方法连接到每个自定义 UIControl 的触摸处理。我应该从 viewController 调用他们的-beginTrackingWithTouch:withEvent:,还是应该让他们实现 customView 的协议?还是有其他方法可以正确处理?

【问题讨论】:

您能否发布您的代码,以便我们了解发生了什么。还有一个原因是您需要使用正方形。画圆不是更容易吗? 我在上面添加了部分代码,虽然我不确定哪一部分是相关的,因为我想知道触摸视图和接收视图之间的连接,以及目前缺少代码。我没有画圆圈,因为我使用的是图像,并且我拥有的每个自定义 UIControl 中都有一个 UIImage。 【参考方案1】:

即使我没有尝试,也没有必要自己计算。 -hitTest:withEvent: 应该适合你。

【讨论】:

谢谢。我想过,但据我所知,我仍然会遇到打电话给-beginTrackingWithTouch:withEvent: 的问题。 -hitTest:withEvent 将返回一个 UIView,但是当我得到它时,我应该如何与该 UIView 交互? 你不应该call hitTest:withEvent:,而是在你的shape view子类中实现它(返回nil,如果事件在圆圈之外)。系统调用它,以获取视图并自行完成其余工作。然后您不必关心实现将消息发送给委托。 Cocoa 会为你做到这一点。

以上是关于跨多个子视图传递 UITouch * 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

七月第四周总结

跨多个子视图处理触摸事件

跨多个子视图的 SwiftUI 拖动手势

从 UITouch 对象调用 UIGestureRecognizer

Laravel 3 - 跨多个视图传递变量

# iOS开发:剖析UITouch传递链和响应链