I want to do an animation that is responsive to device motion and I'd like it to remain smooth even if the UI thread is momentarily busy. The animation consists of changing a CALayer's bezier path. I've tried doing it from a secondary thread but I get occasional hangs where the main thread has a trashed stack. Is what I'm doing totally hopeless? Here's what I do in the thread:
[CATransaction lock];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
[CATransaction begin];
myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
myLayer.bounds = theBounds;
[CATransaction commit];
[CATransaction flush];
[CATransaction setValue:(id)kCFBooleanFalse
forKey:kCATransactionDisableActions];
[CATransaction unlock];
updating the ui from any thread except the uithread is prohibited so you will have to do the following:
- (void) updateUI
{
[CATransaction lock];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
[CATransaction begin];
myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
myLayer.bounds = theBounds;
[CATransaction commit];
[CATransaction flush];
[CATransaction setValue:(id)kCFBooleanFalse
forKey:kCATransactionDisableActions];
[CATransaction unlock];
}
and from the other thread
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];