Animations in iOS are easy, except when they’re not. I learned this the hard way making SKBounceAnimation, when I learned about how explicit animations are so different and weird compared to implicit animations.

Today, I learned a new lesson. You would think something like

mySublayer.cornerRadius = 3;  
myView.frame = CGRectMake(0, 0, 100, 100);

[UIView animateWithDuration:0.25 animations:^{  
	mySublayer.cornerRadius = 5;  
	myView.frame = CGRectMake(50, 50, 100, 100);  
}];  

would just work. But apparently you can’t perform sublayer animations in an animateWithDuration: block, so your CALayer just picks its own duration and timing function, and animates it anyway. This can be a subtle effect, but if you flip the Toggle Slow Animations flag in the Simulator, it becomes super obvious, since CATransactions aren’t affected by that menu item.

The solution is to create a separate CATransaction

mySublayer.cornerRadius = 3;  
myView.frame = CGRectMake(0, 0, 100, 100);

CGFloat duration = 0.18f;

[CATransaction begin];  
[CATransaction setAnimationDuration:duration];  
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] ];  
mySublayer.cornerRadius = 5;  
[CATransaction commit];

[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationCurveEaseInOut animations:^{  
	myView.frame = CGRectMake(50, 50, 100, 100);  
} completion:^(BOOL finished) { }];  

Your CATransaction can be inside your animations block if you like. Apple warns that

This type of mixing should not be used in situations where precise timing is needed.

but it looks pretty dead-on to me. The only information about doing this kind of thing is found in three paragraphs on the Apple documentation site, found here.