For 2018 ...
Couldn't be easier.
Don't forget the [weak self]
or you'll crash.
func animeExample() {
CATransaction.begin()
let a = CABasicAnimation(keyPath: "fillColor")
a.fromValue, duration = ... etc etc
CATransaction.setCompletionBlock{ [weak self] in
self?.animeExample()
self?.ringBell()
print("again...")
}
someLayer.add(a, forKey: nil)
CATransaction.commit()
}
Critical tip:
You MUST have setCompletionBlock
BEFORE the someLayer.add
.
The order is critical! It's an iOS quirk.
In the example, it just calls itself again.
Of course, you can call any function.
Notes for any anyone new to iOS animations:
The "key" (as in forKey
) is irrelevant and rarely used. Set it to nil. If you want to set it, set it to "any string".
The "keyPath" is in fact the actual "thing you are animating". It is literally a property of the layer such as "opacity", "backgroundColor" etc, but written as a string. (You can't just type in "anything you want" there, it has to be the name of an actual property of the layer, and, it has to be animatable.)
To repeat: the "key" (rarely used - just set it to nil) and the "keyPath" are totally unrelated to each other.
You often see example code where these two are confused (thanks to the silly naming), which causes all sorts of problems.
Note that alternately you can use the delegate, but it's far easier to just use the completion block, since (A) it's self-contained and can be used anywhere and (B) you usually have more than one anime, in which case using the delegate is a bore.