Як миттєво перемістити CALayer (без анімації)


80

Я намагаюся перетягнути a CALayerу програмі iOS.

Як тільки я зміню його властивість позиції, вона намагається анімувати нову позицію і мерехтить повсюдно:

 layer.position = CGPointMake(x, y)

Як я можу CALayersнегайно рухатися ? Здається, я не можу розібратися з Core Animation API.


щодо цього надзвичайно старого контролю якості сьогодні найважливішим питанням є: stackoverflow.com/a/56980329/294884
Fattie

Відповіді:


168

Ви хочете завершити свій дзвінок таким чином:

[CATransaction begin]; 
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
layer.position = CGPointMake(x, y);
[CATransaction commit];

1
Ось саме це. Я навіть не думав про транзакцію CAT. Дуже дякую!
Мел

5
Так, через 6 з половиною років. Все ще корисно. : D
Fogmeister

1
iOS7 підтримує нову стенографію:[UIView performWithoutAnimation:<#^(void)actionsWithoutAnimation#>];
k06a

2
7 років, 7 місяців і 17 днів потому: все ще корисно. Дякую!
kanobius

1
великий палець вгору через 9 років
nshuman

32

Розширення Swift 3:

extension CALayer {
    class func performWithoutAnimation(_ actionsWithoutAnimation: () -> Void){
        CATransaction.begin()
        CATransaction.setValue(true, forKey: kCATransactionDisableActions)
        actionsWithoutAnimation()
        CATransaction.commit()
    }
}

Використання:

CALayer.performWithoutAnimation(){
    someLayer.position = newPosition
}

1
Корисно додати @noescapeатрибут до блоку, щоб дозволити (і дати зрозуміти), що selfне потрібно в блоці
Ендрю

22

Ви також можете скористатися функцією зручності

[CATransaction setDisableActions:YES] 

також.

Примітка: Обов’язково прочитайте коментарі Йогева Шеллі, щоб зрозуміти будь-які помилки, які можуть статися.


5
Важливо, це впливає на всі CALayer, тому ви хочете відновити дії після закінчення, тобто [CATransaction setDisableActions: YES]
Йогев Шеллі

Блін, я повинен був це сказати. Добре заощадити. Команда вимикає анімацію, доки не встановлено значення НІ або поки основний графічний анімаційний механізм не завершить цикл запуску. Не впевнений, що це правильне слово для цього: / Але дякую, що ви це зрозуміли для всіх.
Біклоп

15

Як пропонували інші, ви можете використовувати CATransaction.
Проблема виникає, оскільки CALayer має за замовчуванням неявну тривалість анімації 0,25 секунди.

Таким чином, простішою (на мій погляд) альтернативою setDisableActionsє використання setAnimationDurationзі значенням 0.0.

[CATransaction begin];
[CATransaction setAnimationDuration:0.0];
layer.position = CGPointMake(x, y);
[CATransaction commit];

Легко запам’ятовується, легко розуміється, коли ви перечитуєте код, і легше друкується. Дякую!
Містер Т,

3

Поєднуючи тут попередні відповіді для Swift 4, щоб чітко визначити тривалість анімації ...

extension CALayer
{
    class func perform(withDuration duration: Double, actions: () -> Void) {
        CATransaction.begin()
        CATransaction.setAnimationDuration(duration)
        actions()
        CATransaction.commit()
    }
}

Використання ...

CALayer.perform(withDuration: 0.0) {
            aLayer.frame = aFrame
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.