Отключение неявной анимации в - [CALayer setNeedsDisplayInRect:] - PullRequest
128 голосов
/ 11 февраля 2010

У меня есть слой с некоторым сложным кодом рисования в его -drawInContext: метод. Я пытаюсь минимизировать количество рисования, которое мне нужно сделать, поэтому я использую -setNeedsDisplayInRect: для обновления только измененных частей. Это работает великолепно. Однако, когда графическая система обновляет мой слой, он переходит от старого к новому изображению с помощью плавного перехода. Я бы хотел, чтобы он мгновенно переключился.

Я пытался использовать CATransaction, чтобы отключить действия и установить длительность на ноль, но ни одна из них не работает. Вот код, который я использую:

[CATransaction begin];
[CATransaction setDisableActions: YES];
[self setNeedsDisplayInRect: rect];
[CATransaction commit];

Есть ли другой метод для CATransaction, который я должен использовать вместо этого (я также пробовал -setValue: forKey: с kCATransactionDisableActions, тот же результат).

Ответы [ 14 ]

0 голосов
/ 28 мая 2016

Если вам когда-нибудь понадобится очень быстрое (но по общему признанию хакерское) исправление, возможно, стоит просто сделать это (Swift):

let layer = CALayer()

// set other properties
// ...

layer.speed = 999
0 голосов
/ 06 апреля 2016

Попробуйте это.

let layer = CALayer()
layer.delegate = hoo // Same lifecycle UIView instance.

Внимание

Если вы установите делегат экземпляра UITableView, иногда может произойти сбой. (Вероятно, самый быстрый вызов scrollview вызывается рекурсивно.)

0 голосов
/ 11 марта 2016

Чтобы отключить раздражающую (размытую) анимацию при изменении свойства строки 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 столько, сколько хотите =)

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

0 голосов
/ 01 августа 2015

Начиная с iOS 7 есть удобный метод, который делает именно это:

[UIView performWithoutAnimation:^{
    // apply changes
}];
...