点击自定义 UIView 会触发错误的选择器

Posted

技术标签:

【中文标题】点击自定义 UIView 会触发错误的选择器【英文标题】:Tapping on custom UIView fires wrong selector 【发布时间】:2016-01-13 15:47:17 【问题描述】:

我在一个超级视图上有 2 个自定义绘制的子视图和 2 个手势识别器来调用 2 种不同的方法。问题是,当我点击任何视图时,点击第二个子视图仍然会触发第一个方法!这是我的代码:

- (void) addTapGestures
self.firstTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(firstSelector)];
self.firstTap.numberOfTapsRequired = 1;
[self.firstSubview addGestureRecognizer:self.firstTap];

self.secondTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(secondSelector)];
self.secondTap.numberOfTapsRequired = 1;
[self.secondSubview addGestureRecognizer:self.secondTap];

将不胜感激任何提示!

【问题讨论】:

我只是不明白这一行 self.firstSubview = [[UITapGestureRecognizer alloc] ,应该是 self.firstTap = [UITapGesture] @NickCatib 是的,感谢您指出错字,已编辑。 您的代码中有错字。 self.firstSubview = 应该是 self.firstTap = @Tuslareb,是的,我正在更改名称并输入了这个错字。现已编辑。 你的第二个子视图不是第一个子视图的子视图吗? 【参考方案1】:

你可以使用 UIView 的 hitTest 方法来获取被点击的视图。基于此,您可以决定应该调用哪个方法。将此方法放在包含两个子视图的超级视图中。 这是一个例子。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

   UIView *hitView = [super hitTest:point withEvent:event];

   if ([self.firstSubView isEqual:hitView])
   
       // You clicked on firstSubView, by returning firstSubView it will call its respective selector method
       return self.firstSubView;
   
   else if ([self.secondSubView isEqual:hitView])
   
      return self.secondSubView;
   

   return hitView;

【讨论】:

有趣。这个方法是自动调用的吗? @Kmkrn 是的。它是 UIView 的一种方法【参考方案2】:

来自我的 cmets 的回答。我能想到的常见问题: 1) self.firstSubview 等于 self.secondSubview 2) 视图重叠和/或其中之一禁用了用户交互。 第二个结果是个问题。

【讨论】:

【参考方案3】:

Swift 2.0:

试试:-

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 
    view.endEditing(true)
    super.touchesBegan(touches, withEvent: event)

//make condition here

使用 UIPanGestureRecognizer。在 ViewController 中,将识别器安装在“父”视图上。

var pan = UIPanGestureRecognizer(target:self, action:"pan:")
pan.maximumNumberOfTouches = 1
pan.minimumNumberOfTouches = 1
self.view.addGestureRecognizer(pan)

在识别器动作中,首先抓取事件的位置。然后,根据识别器的状态,实现拖动功能的不同部分。

func pan(rec:UIPanGestureRecognizer)             
        var p:CGPoint = rec.locationInView(self.view)
        var center:CGPoint = CGPointZero

        switch rec.state 
        case .Began:
            println("began")
            self.selectedView = view.hitTest(p, withEvent: nil)
            if self.selectedView != nil 
                self.view.bringSubviewToFront(self.selectedView!)
            
case .Changed:
            if let subview = selectedView 
                center = subview.center
                var distance = sqrt(pow((center.x - p.x), 2.0) + pow((center.y - p.y), 2.0))
                println("distance \(distance)")

            if subview is MyView 
                if distance > threshold 
                    if shouldDragX 
                        subview.center.x = p.x - (p.x % snapX)
                    
                    if shouldDragY 
                        subview.center.y = p.y - (p.y % snapY)
                    
                
            
        
case .Ended:
   if let subview = selectedView 
      if subview is MyView 
          // do whatever
      
   
   // must do this of course
   selectedView = nil

【讨论】:

以上是关于点击自定义 UIView 会触发错误的选择器的主要内容,如果未能解决你的问题,请参考以下文章

LayUI laydate日期选择器自定义 快捷选中今天昨天 本周本月等等

LayUI laydate日期选择器自定义 快捷选中今天昨天 本周本月等等

iOS个人中心渐变动画微信对话框标签选择器自定义导航栏短信验证输入框等源码

如何从模态 UIView 更新自定义单元格中的 UIButton 标题

快速放置在函数中时无法触发uiview.animate

如何在 iOS 开发中处理自定义事件?