CALayerを即座に(アニメーションなしで)どのように移動しますか


80

ドラッグしようとしています CALayeriOSアプリで。

位置プロパティを変更するとすぐに、新しい位置にアニメーション化しようとし、あちこちでちらつきます。

 layer.position = CGPointMake(x, y)

どうすればCALayersすぐに移動できますか?Core AnimationAPIに頭を悩ませているようには見えません。


この非常に古いQAに関して、今日の重要な問題は次のとおりです 。stackoverflow.com
a / 56980329/294884 –Fattie20年

回答:


168

通話を次のようにラップします。

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

1
まさにそれです。CATransactionについても考えていませんでした。どうもありがとう!
メル

5
うん、6年半後。それでも役に立ちます。:D
フォグマイスター2014

1
iOS7は新しい速記をサポートします:[UIView performWithoutAnimation:<#^(void)actionsWithoutAnimation#>];
k06a 2014

2
7年、7か月、17日後:まだ役に立ちます。ありがとう!
kanobius 2016年

1
9年後の親指
nshuman 2017

32

Swift 3 Extension:

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不要なものを許可する(そして明確にする)と便利です
Andrew

22

便利機能もご利用いただけます

[CATransaction setDisableActions:YES] 

同様に。

注:Yogev Shellyのコメントを読んで、発生する可能性のある落とし穴を理解してください。


5
重要なことに、これはすべてのCALayerに影響するため、完了後にアクションを再度有効にする必要があります。つまり、[CATransaction setDisableActions:YES]
Yogev Shelly 2012

くそー私はそれを言うべきだった。良い保存。このコマンドは、NOに設定されるまで、またはコアグラフィックアニメーションエンジンが実行サイクルを完了するまで、アニメーションを無効にします。それが正しい言葉かどうかはわかりません:/しかし、皆さんのためにそれをクリアしていただきありがとうございます。
Biclops 2012

15

他の人が示唆しているように、を使用することができますCATransaction
この問題は、CALayerのデフォルトの暗黙的なアニメーション期間が0.25秒であるために発生します。

したがって、(私の意見では)より簡単な代替手段setDisableActionssetAnimationDuration、値をで使用することです0.0

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

覚えやすく、コードを読み直しているときに理解しやすく、入力も簡単です。ありがとう!
ミスターT

3

ここでSwift4の以前の回答を組み合わせて、アニメーションの継続時間を明確にします...

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
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.