Отключить неявную анимацию свойства CATextLayer.string

У меня есть вид с одним подслоем типа CATextLayer. Я переопределяю метод drawRect: views и там меняет свойство CATextLayer.string на экземпляр NSAttributedString. Каждый раз, когда NSAttributedString имеет один и тот же текст, но с разными цветами. На данный момент каждый раз, когда свойство строки изменяется, цвет текста делает анимированный переход в новый цвет.

Можно ли отключить анимацию этого свойства?

Ответ 1

Выяснил это, используя ответ на этот вопрос: Отключение неявных анимаций в - [CALayer setNeedsDisplayInRect:]

В моем конкретном случае, чтобы остановить изменение свойства CATextLayer.string от анимирования, этого кода было достаточно:

NSDictionary *newActions = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"contents", nil];
textLayer.actions = newActions;
[newActions release];

Другими словами, кажется, что ключ contents отключает анимацию при внесении изменений в свойство CATextLayer.string.

Ответ 2

Лучшим решением является использование блока CATransaction для отключения анимации:

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

Чтобы отключить раздражающую (размытую) анимацию при изменении свойства строки CATextLayer, вы можете сделать это:

class CANullAction: CAAction {
    private static let CA_ANIMATION_CONTENTS = "contents"

    @objc
    func runActionForKey(event: String, object anObject: AnyObject, arguments dict: [NSObject : AnyObject]?) {
        // Do nothing.
    }
}

а затем используйте его так (не забудьте правильно настроить ваш CATextLayer, например правильный шрифт и т.д.):

caTextLayer.actions = [CANullAction.CA_ANIMATION_CONTENTS: CANullAction()]

Вы можете увидеть мою полную настройку CATextLayer здесь:

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"

Теперь вы можете обновить caTextLayer.string столько, сколько хотите =)

Вдохновленный этим и этот ответ.