Why the presentationLayer of a view doesn't work correctly for me?
I want to get the position of a view while it is being animated and moving from one position to another I tried to use the presentationLayer to get the action location information, and tried to print out the location when the UIView is moving.
Here is what is printing out:
2010-1开发者_StackOverflow社区2-08 16:56:50.496 Exp[31219:207] point: NSPoint: {45, 45}
2010-12-08 16:56:50.696 Exp[31219:207] point: NSPoint: {45, 45}
2010-12-08 16:56:50.896 Exp[31219:207] point: NSPoint: {45, 45}
2010-12-08 16:56:51.096 Exp[31219:207] point: NSPoint: {45, 45}
2010-12-08 16:56:51.296 Exp[31219:207] point: NSPoint: {45, 45}
2010-12-08 16:56:51.496 Exp[31219:207] point: NSPoint: {245, 245} <<----------------------------------------
2010-12-08 16:56:51.696 Exp[31219:207] point: NSPoint: {245, 245}
2010-12-08 16:56:51.896 Exp[31219:207] point: NSPoint: {245, 245}
2010-12-08 16:56:52.096 Exp[31219:207] point: NSPoint: {245, 245}
notice the arrow, the endpoint is directly printed out without showing points on the path. Can anyone help?
below is my code:
Here's how it is printing:
-(void)print
{ NSLog([NSMutableString stringWithFormat:@"point: %@",[NSValue valueWithCGPoint:((CALayer *)[bomb.layer presentationLayer]).position]]);
}I used a timer to repeatedly print out the animated view "bomb"
-(id)initWithCoder:(NSCoder *)aDecoder
{ if (self=[super initWithCoder:aDecoder]) {
bomb = [[BombView alloc]init];
bomb.frame = CGRectMake(30, 30, 30, 30);
bomb.backgroundColor = [UIColor yellowColor];
[self addSubview:bomb];
timer = [NSTimer timerWithTimeInterval:PRINTINTERVAL // defined to be 0.2
target: self
selector: @selector(print)
userInfo: nil
repeats: YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode: NSDefaultRunLoopMode];
}
return self;
}
Here's how it is animated:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.duration = 10.0;
animation.delegate = bomb;
[bomb.layer addAnimation:animation forKey:@"animatePosition"];
bomb.center = CGPointMake(bomb.center.x+200, bomb.center.y+200);
}
when I click, the "bomb" will move and the information printed out should be gradually changing. Because it is moving at such a low speed within 10 seconds.
It moves fine but doesn't print correctly.
It might be because you're using an NSTimer
to print the diagnostics. That will execute but perhaps not on the main
thread, thereby giving you incorrect results.
You could use a timer, but instead have it fire off a method that in turn invokes another method to do your diagnostics. The latter you will execute on the main
thread using performSelectorOnMainThread
.
timer = [NSTimer timerWithTimeInterval:PRINTINTERVAL // defined to be 0.2
target: self
selector: @selector(timedPrint)
userInfo: nil
repeats: YES];
then:
- (void)timedPrint
{
[self performSelectorOnMainThread:@selector(print)];
}
Alternatively, rather that use the currentRunLoop
use mainRunLoop
.
If that doesn't resolve the query, then it maybe because of course there are three different layers in the Core Animation architecture; model, presentation, and render. So it maybe that the render layer has changed - as you can see - but the presentationLayer
has not yet been updated.
There's quite a few related questions on exactly this issue. For example:
Does the -presentationLayer tell me the in-flight values of an view while it is beeing animated?
Why does one have to use CALayer's presentationLayer for hit-testing?
精彩评论