【问题标题】:UITapGesture not working on dynamically created UIViewsONTapGesture 不适用于动态创建的视图
【发布时间】:2016-04-18 12:00:32
【问题描述】:

我正在通过代码制作动态UIViews 并尝试在它们上添加UITapGestureRecogniser。但由于某种原因,他们没有回应。这是代码:

-(void)createRandomBlock{
    UIView * block = [[UIView alloc] initWithFrame:CGRectMake([self getRandomPosition], 0-_heightOfBlock, _widthOfBlock, _heightOfBlock)];
    block.backgroundColor = [self randomColor];
    block.userInteractionEnabled=YES;

    UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(blockTapped:)];
    tapGesture.delegate = self;
    tapGesture.numberOfTouchesRequired = 1;
    tapGesture.numberOfTapsRequired=1;
    [block addGestureRecognizer:tapGesture];

    [self.view addSubview:block];

    [UIView animateWithDuration:_durationOfAnimation delay:0.0 options:options animations:^{
        [block setFrame:CGRectMake(block.frame.origin.x, ScreenHeight, block.bounds.size.width, block.bounds.size.height)];
    } completion:^(BOOL finished) {
        [block removeFromSuperview];
    }];
}

-(void)blockTapped:(UITapGestureRecognizer*)gesture{
    NSLog(@"I am being called?");
    UIView * block = (UIView*)[gesture view];
    [block removeFromSuperview];
}

有人可以帮忙吗?

谢谢

【问题讨论】:

  • createRandomBlock 是否被调用过一次?
  • 大概你可以看到屏幕上的视图?视图和超级视图上还有哪些其他手势?
  • createRandomBlock 正在使用延迟为 3 秒的计时器调用。另外,我正在使用 uiviewanimate 为视图设置动画。
  • 是的,我可以在那里看到 UIView。我还可以看到它是动画的。
  • 代码已更新。我认为我的 UIViewAnimate 导致了这个问题。

标签: ios objective-c uitapgesturerecognizer


【解决方案1】:

我尝试使用相同的代码,它对我有用。 只是改变存在,我没有为 tapGesture 设置代理

-(void)createRandomBlock{
    UIView * block = [[UIView alloc] initWithFrame:randomPosition];
    block.backgroundColor = [self randomColor];
    block.userInteractionEnabled=YES;

    UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(blockTapped:)];
    tapGesture.numberOfTapsRequired=1;
    [block addGestureRecognizer:tapGesture];

    [self.view addSubview:block];
}

-(void)blockTapped:(UITapGestureRecognizer*)gesture{
    NSLog(@"I am being called?");
    UIView * block = (UIView*)[gesture view];
    [block removeFromSuperview];
}

我猜是因为添加了委托,它会覆盖您指定的选择器并调用委托方法。

【讨论】:

  • 你能试试更新的代码吗?我认为我的 UIViewAnimate 导致了这个问题。
  • @WarisAli:你能正确说出你在动画中想要做什么吗?通过查看代码,在我看来,您正在创建视图,然后在完成后为视图设置动画,然后将其删除。您想何时调用轻触选择器。能不能说的更清楚一点。
  • @WarisAli:这可能会有所帮助:stackoverflow.com/questions/4311645/…
【解决方案2】:

如果您的顶视图的用户交互被禁用,您的手势也将无法识别子视图上的交互。在调用 createRandomBlock 消息之前尝试在某处添加闲置线路。

self.view.userInteractionEnabled = YES;

【讨论】:

  • 是的。启用顶视图交互。那里没有问题。
  • 好吧。您的手势不起作用,因为 UIView 的动画实际上在调用时立即设置了视图的框架。您看到的实际上是视图的表示层,而不是视图本身。
  • 是的。我做了一些研究,我发现了这一点。因此,人们建议添加 UIViewAnimationOptionAllowUserInteraction 可以解决问题,但显然它没有做任何事情:(有什么建议吗?
  • 我知道的唯一解决方案是删除表示层的动画。
【解决方案3】:

你可以在框架集上犯一些小错误。请更改框架集,您可以解决您的问题。

-(void)createRandomBlock{
    int x_coord = arc4random() % 200; //Random number from 0-320  // set random x position 
    int y_coord = arc4random() % 481; //Random number from 0-480  // set random y position

    UIView * block = [[UIView alloc] initWithFrame:CGRectMake(x_coord, y_coord, 100, 100)]; // for testing set width & height 100 * 100
    block.backgroundColor = [UIColor redColor]; // for fix color you can use your change color function
    block.userInteractionEnabled=YES;

    UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(blockTapped:)];
    tapGesture.delegate = self;
    tapGesture.numberOfTouchesRequired = 1;
    tapGesture.numberOfTapsRequired=1;
    [block addGestureRecognizer:tapGesture];

    [self.view addSubview:block];

[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
        [block setFrame:CGRectMake(block.frame.origin.x, 0, block.bounds.size.width, block.bounds.size.height)];
    } completion:^(BOOL finished) {
//        [block removeFromSuperview];
    }];
}

-(void)blockTapped:(UITapGestureRecognizer*)gesture{
    NSLog(@"I am being called?");
    UIView * block = (UIView*)[gesture view];
    [block removeFromSuperview];
}

【讨论】:

  • uiview的边框没有问题。我可以在我的主视图上看到 uiview。块的 x,y,width 和 height 正在其他代码中调整。
  • 你的屏幕高度默认设备高度是多少??请检查我的代码
  • #define ScreenHeight [[UIScreen mainScreen] bounds].size.height
  • 可以设置Y = ScreenHeight,这样就看不到视图控制器了。现在在我的代码中,您会看到自定义视图控制器从底部到顶部。
【解决方案4】:

我不知道你的 [self getRandomPosition] 和 _widthOfBlock 等有什么价值,否则下面的代码在我的演示中可以正常工作。

 -(void)createRandomBlock{

UIView * block = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
block.backgroundColor = [UIColor redColor];
block.userInteractionEnabled=YES;

UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(blockTapped:)];
tapGesture.delegate = self;
tapGesture.numberOfTouchesRequired = 1;
tapGesture.numberOfTapsRequired=1;
[block addGestureRecognizer:tapGesture];

[self.view addSubview:block];
}

-(void)blockTapped:(UITapGestureRecognizer*)gesture{
NSLog(@"I am being called?");
UIView * block = (UIView*)[gesture view];
[block removeFromSuperview];
}

更新:

你应该使用touchesBegan来识别触摸,这是工作代码,

-(void)createRandomBlock{

UIView * block = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
block.backgroundColor = [UIColor redColor];
block.userInteractionEnabled=YES;
block.tag = 100;
self.view.userInteractionEnabled =YES;

UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(blockTapped:)];
//  tapGesture.delegate = self;
// tapGesture.numberOfTouchesRequired = 1;
tapGesture.numberOfTapsRequired=1;


[block addGestureRecognizer:tapGesture];
[self.view addSubview:block];




 [UIView animateWithDuration:5.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
    [block setFrame:CGRectMake(block.frame.origin.x, self.view.frame.size.height-200, block.bounds.size.width, block.bounds.size.height)];


} completion:^(BOOL finished) {
    [block removeFromSuperview];
}];


}

-(void)blockTapped:(UITapGestureRecognizer*)gesture{

NSLog(@"I am being called?");
UIView * block = (UIView*)[gesture view];
[block removeFromSuperview];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
UIView *tempView = [self.view viewWithTag:100];

if ([tempView.layer.presentationLayer hitTest:touchLocation]) {

    NSLog(@"call");
    [tempView removeFromSuperview];
}


}

【讨论】:

  • 请忽略我正在使用的随机函数和变量。他们工作正常。
  • 检查我更新的答案,它符合您的要求。 :)
【解决方案5】:

您正在删除完成块中的视图,这意味着动画完成后您的视图将被删除。从完成块中删除以下行。

[block removeFromSuperview];

你不应该那样做。您的视图本身已被移除,点击手势将如何工作。

【讨论】:

  • 视图离开屏幕后被移除。
  • 我在动画期间点击它。
  • 我试过把这条线去掉。什么都没做。手势仍然不起作用
  • [block setFrame:CGRectMake(block.frame.origin.x, ScreenHeight, block.bounds.size.width, block.bounds.size.height)]; ScreenHeight 已经是屏幕的高度,y 原点坐标是 ScreenHeight,这意味着它将从屏幕下方开始。将 Y 轴设置为要在显示视图中显示的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
相关资源
最近更新 更多