![](/img/trans.png)
[英]UITapGestureRecognizer on a subview of MKAnnotationView not working
[英]UITapGestureRecognizer not responding on animated subview
我有一個簡單的程序,可以創建一個子視圖並在屏幕上設置動畫。
作為該程序的一部分,我想在點擊子視圖時添加功能。 我使用以下方法創建子視圖,添加UITapGestureRecognizer,然后為子視圖設置動畫:
int randomName = arc4random() % ([pieceNames count] - 1);
int animationDuration = arc4random() % 5 + 5 ;
NSString *randomPiece = [pieceNames objectAtIndex:randomName];
float yStart = arc4random() % 650;
float yEnd = arc4random() % 650;
UIView *piece = [[PieceView alloc]initWithFrame:CGRectMake(100.0, yStart, 75.0, 75.0)];
[piece setValue:randomPiece forKey:@"name"];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]initWithTarget:self
action:@selector(handleTouch:)];
[piece addGestureRecognizer:recognizer];
[[self view] addSubview:piece];
[UIView animateWithDuration:animationDuration
delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^(void){
piece.center = CGPointMake(950.0, yEnd);
} completion:^(BOOL done){
[piece removeFromSuperview];
}];
以下是處理點按的代碼:
PieceView *pv = (PieceView *) recognizer.view;
NSLog(@"%@ was tapped", pv.name);
觸摸PieceView時程序沒有響應會發生什么。 但是,如果我刪除動畫塊,則程序會響應該點擊。
為什么UITapGestureRecognizer在動畫時無法響應PieceView?
我有同樣的問題掙扎,並把它歸結為一點:動畫視圖永遠只能是在兩個地方:起始位置和結束位置。 核心動畫只需在一段時間內在起點和終點之間的插值位置渲染視圖的圖層。
這幾乎是當你看看星星,並認識到你所看到的實際上不是現在發生的事情一樣。 :)
幸運的是,解決方案非常簡單。 您可以在超級視圖上放置一個水龍頭識別器,然后檢查您的動畫視圖的presentationLayer
(它可以在任何時間點為您提供准確的幀),以確定您的點擊是否是一個命中。
我已經構建了一個簡單的UIViewController
來演示問題和解決方案:
#import <UIKit/UIKit.h>
@interface MSMViewController : UIViewController
@end
並實施:
#import "MSMViewController.h"
@interface MSMViewController ()
@property (nonatomic, strong) UIView *animatedView;
@end
@implementation MSMViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGRect startFrame = CGRectMake(125, 0, 70, 70);
CGRect endFrame = CGRectMake(125, 400, 70, 70);
// draw a box to show where the animated view begins
UIView *startOutlineView = [[UIView alloc] initWithFrame:startFrame];
startOutlineView.layer.borderColor = [UIColor blueColor].CGColor;
startOutlineView.layer.borderWidth = 1;
[self.view addSubview:startOutlineView];
// draw a box to show where the animated view ends
UIView *endOutlineView = [[UIView alloc] initWithFrame:endFrame];
endOutlineView.layer.borderColor = [UIColor blueColor].CGColor;
endOutlineView.layer.borderWidth = 1;
[self.view addSubview:endOutlineView];
self.animatedView = [[UIView alloc] initWithFrame:startFrame];
self.animatedView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:self.animatedView];
[UIView animateWithDuration:10 delay:2 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.animatedView.frame = endFrame;
} completion:nil];
// this gesture recognizer will only work in the space where endOutlintView is
UITapGestureRecognizer *boxTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(boxTap:)];
[self.animatedView addGestureRecognizer:boxTap];
// this one will work
UITapGestureRecognizer *superviewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(superviewTap:)];
[self.view addGestureRecognizer:superviewTap];
}
- (void)boxTap:(UITapGestureRecognizer *)tap {
NSLog(@"tap. view is at %@", NSStringFromCGPoint(self.animatedView.frame.origin));
}
- (void)superviewTap:(UITapGestureRecognizer *)tap {
CGRect boxFrame = [self.animatedView.layer.presentationLayer frame];
if (CGRectContainsPoint(boxFrame, [tap locationInView:self.view])) {
NSLog(@"we tapped the box!");
}
}
@end
解決方案要簡單得多,您只需要設置動畫的選項UIViewAnimationOptions.allowUserInteraction 。
UIView.animate(withDuration: duration, delay: 0.1, options: [.allowUserInteraction], animations: {
...
}, completion: { (completed) in
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.