Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITapGestureRecognitor仅检测父视图点击_Ios_Objective C - Fatal编程技术网

Ios UITapGestureRecognitor仅检测父视图点击

Ios UITapGestureRecognitor仅检测父视图点击,ios,objective-c,Ios,Objective C,我正在使用UIAPTgestureRecognitor检测屏幕上点击的UIView,但由于某些原因,它只检测父视图点击,例如下面的代码记录仅父视图标记。如何检测主视图上存在的子视图点击。请建议 Inside View did load :- UITapGestureRecognizer *viewTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionForViewT

我正在使用UIAPTgestureRecognitor检测屏幕上点击的UIView,但由于某些原因,它只检测父视图点击,例如下面的代码记录仅父视图标记。如何检测主视图上存在的子视图点击。请建议

Inside View did load :- 

UITapGestureRecognizer *viewTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionForViewTapped:)];
    [self.view addGestureRecognizer:viewTapRecognizer];
方法外部视图没有加载

-(void) actionForViewTapped:(UITapGestureRecognizer*)sender {
    NSLog(@"view tapped");
    UIView *view = sender.view;
    NSLog(@"view tag is %lu", view.tag); //Always prints parent view tag. 

    if(view.tag == 10){
        NSLog(@"tag1 tapped"); //Not called
    }
    if(view.tag == 20){
        NSLog(@"tag 2 tapped"); //Not called
    }
}

手势识别器仅与一个特定视图关联,这意味着它将仅识别添加到视图上的触摸。如果您想知道触摸了哪个子视图,则需要执行以下几项操作:

  • 为每个子视图设置
    userInteractionEnabled=false
    。这将使子视图上的每一次触摸都被传递到父视图,并且手势识别器将识别该触摸
  • 关于视图层次结构或布局的信息不足,无法确切了解如何从这里开始,但您可以使用以下一种或某些方法来确定触动了哪个视图:
    UIView.hitTest(:with:)
    UIView.point(内部:with:)
    CGRectContainsPoint()
    uigestureRecogragnizer.location(in:)
    。例如,如果子视图彼此不重叠,则可以使用以下代码段测试触摸是否位于特定视图中:

    let location = tapGesture.locationInView(parentView)
    if CGRectContainsPoint(subview1, location) {
        // subview1 was touched
    }
    

  • 我们有更多的选项可以通过点击手势在子视图中找到检测

    选项1:直接点击子视图

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapSubView)];
    tapGesture.numberOfTapsRequired = 1;
    [subView addGestureRecognizer:tapGesture];
    
    选择2:通过父视图在子视图上查找点击

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapSubView)];
    tapGesture.numberOfTapsRequired = 1;
    [self.view addGestureRecognizer:tapGesture];
    
    
    -(void)tapSubView:(UITapGestureRecognizer *)sender
    {
       UIView* view = sender.view;
       CGPoint loc = [sender locationInView:view];
       UIView* subview = [view hitTest:loc withEvent:nil];
                   //OR
       CGPoint point = [sender locationInView:sender.view];
       UIView *viewTouched = [sender.view hitTest:point withEvent:nil];
    
       if ([viewTouched isKindOfClass:[self.view class]])
       {
          NSLog(@"the subView is called");
       } 
       else 
       {
          NSLog(@"the subView is not called");
       }
    }
    
    打印输出为

    the subView is called
    
    选项3:使用手势的代理方法查找点击检测

    首先,您必须添加手势识别器委托

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
    {
      if([touch.view isKindOfClass: [self.view class]] == YES)
      {
        return YES; // return YES (the default) to allow the gesture recognizer to examine the touch object
      }
      else {
        return NO;  //NO to prevent the gesture recognizer from seeing this touch object.
      }
    }
    

    这看起来很复杂,是一个解决办法,是否有其他方法可以将操作添加到UIView的点击中,我尝试过将视图设置为UIControl,但即使这样也不起作用。这不是一个解决办法。这是视图/触摸系统的工作方式。备选方案高度取决于视图层次结构的外观。有些“复杂”永远不应该阻止你去探索它。虽然我写了很多文字来解释发生了什么,但我写的实际代码是3行;这一点都不复杂。探索这条途径将帮助你了解更多关于系统如何工作的信息,并帮助你在将来为自己解决这些问题。你不能总是依赖一行代码复制/粘贴SO的答案。我想您在子视图上的权利解释谢谢,但我在UIView上添加了一个透明按钮和一个动作,效果很好。您希望在按下按钮时触发点击手势和正常按钮动作吗?是的。您的权利,我想检测我的一个视图点击,并在其上有一个动作。