Il semble que la couche ne reçoit pas seulement des touches sur les pixels inférieurs. Au lieu de cela, il semble que le "réel" à l'écran et le contenu de la couche sont définis par différents CGRects. L'image est affichée aux coordonnées souhaitées, tandis que la couche qui répond aux touches est décalée sous l'image. Par ci-dessous, je veux dire l'origine de l'image est à (200, 200) et l'origine de la couche qui répond aux touches est à (200, 220). Ci-dessous, je poste un code de test que j'ai utilisé pour recréer le problème. D'abord ma sous-classe vue puis mon contrôleur de vue. Tout raisonnement derrière ce problème est grandement apprécié.
Ma Voir sous-classe:
#import "myView.h"
#import <QuartzCore/QuartzCore.h>
@implementation myView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint currentLocation = [[touches anyObject] locationInView:self];
CALayer *currentLayer = [self.layer hitTest:currentLocation];
CGPoint center = [currentLayer position];
NSLog([currentLayer valueForKey:@"isRootLayer"]);
if(![currentLayer valueForKey:@"isRootLayer"]) {
if (center.x != 200) {
[currentLayer setPosition:CGPointMake(200.0f, 200.0f)];
} else {
[currentLayer setPosition:CGPointMake(100.0f, 100.0f)];
}
}
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void)dealloc {
[super dealloc];
}
@end
Mon View Controller:
#import "layerTestViewController.h"
#import <QuartzCore/QuartzCore.h>
#define ELEMENT_PERIOD_SIZE 50
#define ELEMENT_GROUP_SIZE 50
@implementation layerTestViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *myLayer = [CALayer layer];
CGRect layerFrame =CGRectMake(0.0f, 0.0f, ELEMENT_GROUP_SIZE, ELEMENT_PERIOD_SIZE);
myLayer.frame = layerFrame;
[myLayer setName:[NSString stringWithString:@"test"]];
[myLayer setValue:[NSString stringWithString:@"testkey"] forKey:@"key"];
UIGraphicsBeginImageContext(layerFrame.size);
[[UIColor blueColor] set];
UIRectFill(layerFrame);
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
myLayer.contents = (id)[theImage CGImage];
myLayer.position = CGPointMake(100.0f, 100.0f);
[self.view.layer addSublayer:myLayer];
[self.view.layer setValue:[NSString stringWithString:@"YES"] forKey:@"isRootLayer"];
NSLog([self.view.layer valueForKey:@"isRootLayer"]);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[super dealloc];
}
@end
Merci! J'ai eu le même problème, et ça me rendait fou. Je suis encore un peu confus quant à savoir pourquoi c'est nécessaire, mais ça semble fonctionner. –
Je pense qu'un problème est que les coordonnées de la vue CA sont ignorées des coordonnées UIView (en bas à gauche est l'origine)? Mais j'aimerais entendre quelqu'un qui peut élaborer sur la hiérarchie de la vue et de la couche et expliquer vraiment ce qui se passe d'autre. –
Cette réponse m'a sauvé beaucoup de temps et de peine - merci! Il y a encore quelque chose que je ne comprends pas: si 'self' est la vue qui a reçu le toucher, alors' self.layer' est son calque correspondant - alors qu'est-ce que 'self.layer.superlayer'? – wcochran