Disable Implicit Animation of CATextLayer.string P

2019-03-30 06:32发布

问题:

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?

回答1:

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.



回答2:

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()


回答3:

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.