CALayer를 즉시 이동하는 방법 (애니메이션없이)


80

CALayeriOS 앱에서 드래그하려고합니다 .

위치 속성을 변경하자마자 새 위치로 애니메이션을 시도하고 모든 곳에서 깜박입니다.

 layer.position = CGPointMake(x, y)

어떻게 CALayers즉시 이동할 수 있습니까? Core Animation API에 대해 머리를 이해할 수없는 것 같습니다.


이 매우 오래된 QA와 관련하여 오늘 중요한 문제는 다음과 같습니다. stackoverflow.com/a/56980329/294884
Fattie

답변:


168

다음에서 통화를 래핑하려고합니다.

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

1
그게 바로 그것입니다. 나는 CATransaction을 생각조차하지 않았다. 감사합니다!
Mel

5
그래, 6 년 반 후. 여전히 도움이됩니다. : D
Fogmeister

1
iOS7은 새로운 속기를 지원합니다.[UIView performWithoutAnimation:<#^(void)actionsWithoutAnimation#>];
k06a 2014

2
7 년, 7 개월, 17 일 후 : 여전히 도움이됩니다. 감사!
kanobius

1
나중에 구년 엄지 손가락
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필요하지 않은 것을 허용하고 명확하게하기 위해 블록에 속성 을 추가하는 것이 유용합니다.
Andrew

22

편의 기능을 사용할 수도 있습니다.

[CATransaction setDisableActions:YES] 

게다가.

참고 : 발생할 수있는 문제를 이해하려면 Yogev Shelly의 의견을 읽어보십시오.


5
[: YES CATransaction의 setDisableActions] 중요,이 효과 모두의 CALayer 당신은 당신이, 예를 완료 한 후 다시 활성화 행동 할 수 있도록
Yogev 셸리

젠장 내가 말 했어야 했어. 잘 저장했습니다. 이 명령은 NO로 설정되거나 코어 그래픽 애니메이션 엔진이 실행주기를 완료 할 때까지 애니메이션을 비활성화합니다. 그것이 올바른 단어인지 확실하지 않습니다 : / 그러나 모두를 위해 그것을 정리해 주셔서 감사합니다.
Biclops

15

다른 사람들이 제안했듯이 CATransaction.
CALayer의 기본 암시 적 애니메이션 기간이 0.25 초이기 때문에 문제가 발생합니다.

따라서 (내 의견으로는) 의 값과 함께 setDisableActions사용 하는 것이 더 쉽습니다 .setAnimationDuration0.0

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

기억하기 쉽고 코드를 다시 읽을 때 이해하기 쉬우 며 입력하기 쉽습니다. 감사!
Mr. T

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
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.