ONTapGesture 不适用于动态创建的视图
Posted
技术标签:
【中文标题】ONTapGesture 不适用于动态创建的视图【英文标题】:UITapGesture not working on dynamically created UIViews 【发布时间】: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 导致了这个问题。 【参考方案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:这可能会有所帮助:***.com/questions/4311645/…【参考方案2】:如果您的顶视图的用户交互被禁用,您的手势也将无法识别子视图上的交互。在调用 createRandomBlock 消息之前尝试在某处添加闲置线路。
self.view.userInteractionEnabled = YES;
【讨论】:
是的。启用顶视图交互。那里没有问题。 当然。这是所需的文件。 dropbox.com/sh/puwc6gv09tm0kb4/AAAMEI6mUfXhWplVmOXsBazDa?dl=0 好吧。您的手势不起作用,因为 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 轴设置为要在显示视图中显示的内容。以上是关于ONTapGesture 不适用于动态创建的视图的主要内容,如果未能解决你的问题,请参考以下文章
动态 PHP 变量不适用于使用 mPDF 的 codeigniter php 视图文件
iOS + Swift 2:UITableViewCell 中的动态高度不适用于空视图
为 android ListView 设置空视图不适用于在 Java 中创建的视图