【问题标题】:How to pass touches from UIView to UIScrollView如何将触摸从 UIView 传递到 UIScrollView
【发布时间】:2011-11-21 06:13:38
【问题描述】:

类似于this thread 和许多其他人,我有一个带有NIB 文件的视图控制器,它具有这种布局...

  • 一个。 UIView (480 x 320) - 存储背景图片
  • 乙。 UIScrollView (480 x 220) - 是一个级别选择器滚动视图
  • c。 UIView (480 x 320) - 包含一个前景动画图形

以上三个项目都是NIB中主视图的子视图。 UIView (c) 是 iPhone 屏幕的全尺寸,位于层次结构的顶部。在它上面,我放置了一个角色,该角色根据该视图中的当前触摸位置进行动画处理。但是问题是,当这个视图接收触摸时,我无法触摸到它下面的 ScrollView (b)。我仍然需要在 (c) 处使用触摸,但之后还需要将相关的触摸/滑动传递给下面的 UIScrollView。

谁能建议如何做到这一点?我已经阅读了有关使用 hittest 的各种帖子,但不想完全抵消触摸,我只需要在之后转发它们,以便滚动视图仍然正常工作。

谢谢,

【问题讨论】:

    标签: iphone objective-c uiview uiscrollview


    【解决方案1】:

    如果是我,我会将 scrollView 设置为顶视图的委托。当然,这需要顶视图是UIView 的自定义子类,因此您可以设置

    id delegate; 
    

    @property (nonatomic, assign) id delegate;
    

    在头文件中。然后,您可以将 scrollView 设置为委托,其中包含

    [topView setDelegate:scrollView];
    

    有了这个,您可以在必要时将消息(在您的情况下为触摸事件)发送到滚动视图。例如,如果您想发送所有 touchBegan 事件,您将拥有:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.delegate touchesBegan:touches withEvent:event];
    }
    

    当然,如果您只想传递某些事件,您可以在方法中设置参数来说明何时调用[self.delegate ....][super ....]。后者将为视图而不是在滚动视图中执行操作。我希望这会有所帮助

    【讨论】:

    • 这个问题是在滚动视图中没有检测到滑动 - 我在进入我现在所处的“状态”之前尝试过这种方法。大声笑......这是一个状态!但是,您确实让我考虑传递动画所需的信息,但没有触摸事件。我会调查这个!
    • 哈哈,这种感觉我太清楚了。但我很高兴这让你想到了解决问题的新方法。对于此类问题,这通常是我的默认设置。基本上只需设置向委托发送事件并从那里开始的条件,无论是手势、触摸还是其他。如果您需要更多控制,您可以继承 scrollView 并从顶部视图采用自定义协议,该协议指定调用哪些方法以及如何实现它们。我希望这不会令人困惑,但如果您想尝试一下,我很乐意为您提供帮助
    • 是的,这当然是一个设计问题——我总是知道我什么时候做的事情很愚蠢,因为它“感觉”像是糟糕的编程!不过感谢您的建议。
    • 没问题。我总是很乐意提供帮助。我希望你能尽快解决所有问题。
    • 尝试添加这个:[super touchesBegan:touches withEvent:event];另请注意,如果您要覆盖其中一种触摸处理方法,则需要覆盖所有四个:touchesBegan、touchesMoved、touchesEnded 和 touchesCancelled。
    【解决方案2】:

    这里有一个对我很有效的更简单的解决方案:

    在视图 C(UIScrollView 上方的前景视图)中,将宽度和高度都设为 0(这样视图在技术上不再位于滚动视图之上)并设置 clipsToBounds = NO(这样视图 C 仍然显示在滚动视图的顶部)。它对我来说就像一个魅力。

     self.viewC.clipsToBounds = NO;
     CGRect frame = self.viewC.frame;
     self.viewC.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);
    

    请注意,如果视图 C 包含交互式控件,则它们将不再起作用。

    【讨论】:

    • 非常聪明。帮了我一些忙。
    • 如果 origin 是 0 你可以使用 CGRectZero 代替,更干净。
    • 你不能直接将 .userInteractionEnabled 设置为 NO/false 吗?
    【解决方案3】:

    继承 UIScrollVeiw 并覆盖 touchesShouldCancelInContentView: 方法,如下所示:

    -(BOOL)touchesShouldCancelInContentView:(UIView *)view
    {
    
        if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to override
            return YES;
        }
    
        if ([view isKindOfClass:[UIControl class]]) {
            return NO;
        }
    
        return YES;
    }
    

    【讨论】:

    • 可能是因为视图 ​​C 不是滚动视图的子视图,因此不会包含在 touchesShouldCancelInContentView 测试中。 (我猜这就是为什么有人反对你)
    猜你喜欢
    • 2014-01-12
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多