代码之家  ›  专栏  ›  技术社区  ›  Aviad Ben Dov

hitTest返回错误的UIView

  •  5
  • Aviad Ben Dov  · 技术社区  · 14 年前

    由于某些原因,视图上的按钮没有被单击;进一步研究表明,当滚动视图接收touchBegind事件时,按钮没有。调用hitTest:event:message显示按钮未返回,即使它在限制范围内。

    应该 被称为。。。

    有人能解释一下吗?我遗漏了什么吗?

    touched ({451, 309}) on <VCViewContainersView: 0x4b31ee0; frame = (0 0; 748 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x4b32130>> (location in expected item: {17, 7.5})
    expected touched item is:
    view: <UIButtonLabel: 0x482b920; frame = (32 5; 36 19); text = 'Click'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4831370>>, layer transform: [1, 0, 0, 1, 0, 0]
     view: <UIRoundedRectButton: 0x482c100; frame = (50 50; 100 30); opaque = NO; layer = <CALayer: 0x482c450>>, layer transform: [1, 0, 0, 1, 0, 0]
      view: <UIImageView: 0x480f290; frame = (0 0; 320 255); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x480e840>>, layer transform: [1, 0, 0, 1, 0, 0]
       view: <VCViewContainer: 0x4b333c0; frame = (352 246.5; 320 471.75); layer = <CALayer: 0x4b33d50>>, layer transform: [1, 0, 0, 1, 0, 0]
        view: <UIScrollView: 0x4b32600; frame = (0 0; 1024 748); clipsToBounds = YES; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x4b32780>>, layer transform: [1, 0, 0, 1, 0, 0]
         view: <VCViewsContainerView: 0x4b31ee0; frame = (0 0; 748 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x4b32130>>, layer transform: [0, 1, -1, 0, 0, 0]
          view: <UIWindow: 0x4b1d590; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4b1d6d0>>, layer transform: [1, 0, 0, 1, 0, 0]
    

    更新 :除 VCVIEWS容器视图 ,所有视图都是使用 或者在按钮的情况下, 按钮类型: CGRectZero公司 UIImageView视图 创建时,其帧设置为图像的大小+底部标签的附加空间。

    :调用时 在相同的位置,我得到 对的 看!怎么回事。。。?

    3 回复  |  直到 14 年前
        1
  •  5
  •   matt    14 年前

    hitTest:withEvent:从窗口开始。每个视图在递归地测试自身之前测试其子视图,依此类推。但是,如果视图的userInteractionEnabled为NO,则它从hitTest:withEvent:返回nil,而不测试其子视图。这样的视图当然是经过hit测试的,但它立即回复说,它或它的任何子视图都不是hit视图。

    您的UIScrollView将其userInteractionEnabled设置为NO。因此,当vcViewContainerView测试其子视图UIScrollView时,UIScrollView返回nil,因为其userInteractionEnabled为NO,vcViewContainerView使用pointInside:withEvent:on本身,发现触摸在其内部,并将其作为点击视图返回(和搜索结束)。这解释了你得到的结果。

    当您通过层进行命中测试时,不会发生这种情况的原因是层是不可触摸的,并且对触摸的规则一无所知,因此它们忽略userInteractionEnabled,这是一个视图功能,而不是层功能。层命中测试是一种权宜之计,只在视图包含整个层层次结构(没有视图层次结构)并且您希望模拟特定层是可触摸的时使用。这些文档确实告诉您,层的hitTest:的逻辑与视图的hitTest:withEvent:的逻辑不同,尽管它们无法确切地解释如何实现。

        2
  •  1
  •   crgt    13 年前

    您可能希望尝试子类化UIScrollView,以接收对其中对象的触摸。

    这是一个工作子类。多亏了这么一个社区,因为我相信我原来在这里发现了这样的东西,只是现在挖不到原来的帖子。

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface TouchScroller : UIScrollView 
    {
    }
    
    @end
    

    以及.m:

    #import "TouchScroller.h"
    
    
    @implementation TouchScroller
    
    - (id)initWithFrame:(CGRect)frame 
    {
    return [super initWithFrame:frame];
    }
    
    - (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
    {   
    // If not dragging, send event to next responder
    if (!self.dragging) 
        [self.nextResponder touchesEnded: touches withEvent:event]; 
    else
        [super touchesEnded: touches withEvent: event];
    }
    
    @end
    

    应该可以。

        3
  •  0
  •   Vladimir    14 年前

    userInteractionEnabled 属性设置为否(默认情况下)-因此图像视图及其所有子视图将不会收到任何触摸事件。

    设置图像视图 属性到 YES 必须解决问题