I have a view with one sublayer of type CATextLayer. I override the views drawRect: method and in there change the CATextLayer.string property to an instance of NSAttributedString. Each time the NSAttributedString has the same text but with different colors. As of now each time the string property changes, the text color makes an animated transition into the new color.
Is there any way I can disable the animation of this property?
Figured it out, using the answer for this question: Disabling implicit animations in -[CALayer setNeedsDisplayInRect:]
In my particular case, to stop the changing of the CATextLayer.string
property from being animated, this code was enough:
NSDictionary *newActions = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"contents", nil];
textLayer.actions = newActions;
[newActions release];
In other words, it seems that the contents
key disables animations on changes to the CATextLayer.string
property.
A better solution is to use a CATransaction
block to disable animations like so:
Objective-C
[CATransaction begin];
[CATransaction setDisableActions:YES];
myTextLayer.string = @"Hello world";
[CATransaction commit];
Swift:
CATransaction.begin()
CATransaction.setDisableActions(true)
myTextLayer.string = "Hello world"
CATransaction.commit()
To disable the annoying (blurry) animation when changing the string property of a CATextLayer, you can do this:
class CANullAction: CAAction {
private static let CA_ANIMATION_CONTENTS = "contents"
@objc
func runActionForKey(event: String, object anObject: AnyObject, arguments dict: [NSObject : AnyObject]?) {
// Do nothing.
}
}
and then use it like so (don't forget to set up your CATextLayer properly, e.g. the correct font, etc.):
caTextLayer.actions = [CANullAction.CA_ANIMATION_CONTENTS: CANullAction()]
You can see my complete setup of CATextLayer here:
private let systemFont16 = UIFont.systemFontOfSize(16.0)
caTextLayer = CATextLayer()
caTextLayer.foregroundColor = UIColor.blackColor().CGColor
caTextLayer.font = CGFontCreateWithFontName(systemFont16.fontName)
caTextLayer.fontSize = systemFont16.pointSize
caTextLayer.alignmentMode = kCAAlignmentCenter
caTextLayer.drawsAsynchronously = false
caTextLayer.actions = [CANullAction.CA_ANIMATION_CONTENTS: CANullAction()]
caTextLayer.contentsScale = UIScreen.mainScreen().scale
caTextLayer.frame = CGRectMake(playbackTimeImage.layer.bounds.origin.x, ((playbackTimeImage.layer.bounds.height - playbackTimeLayer.fontSize) / 2), playbackTimeImage.layer.bounds.width, playbackTimeLayer.fontSize * 1.2)
uiImageTarget.layer.addSublayer(caTextLayer)
caTextLayer.string = "The text you want to display"
Now you can update caTextLayer.string as much as you want =)
Inspired by this, and this answer.