The problem is that it is not possible to define a synchronization function for animations based on UIView. As far as I can tell, you are left with a lot of unpleasant options:
- Switch to using CALayer-based animations - with a serious problem: if the delegate is set up for presentation, the animation will not happen. Since this is required for UIViews, this is an unattractive option.
- Add a parent layer to your views and animate this layer - with the same serious problem that this layer is nowhere in nib, and changes to nib can inadvertently break animations.
- Do not use the custom sync function.
I hacked my way by setting the delegate to zero before the animation and returning to the UIView right after, but it feels very dirty. However, maybe I missed something. My code looks something like this:
- (void)methodThatAnimates { [CATransaction begin]; { self.viewToAnimate.layer.delegate = nil; CAMediaTimingFunction *timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.4 :0 :0 :1.0]; [CATransaction setAnimationTimingFunction:timingFunction] self.viewToAnimate.layer.position = CGPoint(15.0, 0.0); self.viewToAnimate.layer.delegate = self.viewToAnimate; } [CATransaction commit]; }
While this seems like a charm, but all the time I expect the appearance of some bizarre artifact due to a temporarily absent delegate.
source share