【问题标题】:Passing events to another object in iOS Objective C将事件传递给iOS Objective C中的另一个对象
【发布时间】:2013-10-18 00:32:49
【问题描述】:

我有一个全屏 UIScrollView,它根据当前滚动位置执行自定义操作。在位于其上方但不在同一层次结构中的图层上,我有一个 UIImageView,它具有一个轻击手势识别器,可将控制权发送到给定的选择器。

我的目标是这样的:

  • 如果用户点击 UIImageView,点击手势识别器会运行选择器(发生这种情况)
  • 如果用户在屏幕上的其他位置向上或向下滑动,UIScrollView 委托会发挥其魔力(也会发生这种情况)
  • 如果用户从 UIImageView 发起滑动(滚动),则将事件传递给 UIScrollView(这不会发生)

如果 UIImageView 是 UIScrollView 的子视图,我知道这可以实现,但我想避免这种情况,因为 UIImageView 并不意味着随着 UIScrollView 的内容滚动。无论如何,我可以将 UIImageView 中的“滚动”触摸事件传递给 UIScrollView 对象,而不使其成为滚动视图的子视图?

【问题讨论】:

    标签: ios objective-c uiscrollview uiimageview


    【解决方案1】:

    您可以在图像视图点击手势识别器上使用requireGestureRecognizerToFail: 来传递滚动视图的平移手势识别器。如果滚动视图的手势识别器不接受该事件,这应该只激活点击手势识别器。

    【讨论】:

    • 这似乎是最好的解决方案。但是这不应该起作用吗(由于某种原因它不起作用)? scrollView 不是 imageLogo 的超级视图绝对可以吗? UITapGestureRecognizer *tapLogo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnLogo:)]; [tapLogo 要求GestureRecognizerToFail:self.scrollView.panGestureRecognizer]; [self.imageLogo addGestureRecognizer:tapLogo];
    • @Aron 嗯,如果视图不是滚动视图的子视图,则可能是不可能的。但是为什么不将它添加到层次结构中呢?即使在滚动滚动视图时,您也可以通过一些数学运算轻松地将其锁定到位。
    • 是的,我想我会这样做,因为我找不到解决层次结构问题的方法。我想避免移动对象,假设虽然数学很容易,但它会对性能产生影响。我们会看到...
    【解决方案2】:

    我想提出以下解决方案。

    AIImageView.m:

    #import "AIImageView.h"
    
    @implementation AIImageView
    {
        NSInteger _cnt;
    }
    
    - (id)initWithImage: (UIImage*)image
    {
        if ((self = [super initWithImage:image]))
        {
            [self setUserInteractionEnabled: YES];
    
            UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self
                                                                                         action: @selector(handleTapGesture:)];
            tapGesture.delegate = self;
            [self addGestureRecognizer: tapGesture];
    
            _cnt = 0;
        }
        return self;
    }
    
    - (UIView*) hitTest: (CGPoint) point withEvent: (UIEvent*) event
    {
        CGPoint result = [self convertPoint: point toView: self.scrollView];
    
        _cnt++;
    
        if (CGRectContainsPoint(self.frame, result))
        {
            if (_cnt > 2)
            {
                _cnt = 0;
            }
            else
            {
                return self.scrollView;
            }
        }
    
        return [super hitTest: point withEvent: event];
    }
    
    - (void) handleTapGesture: (id) sender
    {
        NSLog(@"TAP!!!");
    }
    
    @end
    

    AIImageView.h:

    #import <UIKit/UIKit.h>
    
    @interface AIImageView : UIImageView <UIGestureRecognizerDelegate>
    
    @property(nonatomic, strong) UIScrollView* scrollView;
    
    @end
    

    创建图像视图:

    UIImage* image = [UIImage imageNamed: @"default_cover.png"];
    imageView = [[AIImageView alloc] initWithImage: image];
    imageView.frame = CGRectMake(100, 400, 100, 100);
    imageView.scrollView = self.scrollView;
    [self.view addSubview: imageView];
    

    如果您尝试一下,您会发现此解决方案有效,但并非总是如此:)。但我相信它可以帮助你。

    【讨论】:

    • 这会使图像视图不可点击。
    • 与上面的解决方案一样,从我的测试来看,这似乎只有在 UIImage 是 UIScrollView 的子视图时才有效。我试图避免这种情况,但我想这似乎是不可避免的。
    猜你喜欢
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多