programing

CALayer를 위한 애니메이션 종료 콜백?

goodsources 2023. 9. 3. 16:14
반응형

CALayer를 위한 애니메이션 종료 콜백?

저는 CALayer에서 애니메이션에 대한 콜백이 어디에 있는지 궁금합니다.특히 프레임, 위치 등을 변경하는 것과 같은 암시적인 애니메이션의 경우.UI 보기에서 다음과 같은 작업을 수행할 수 있습니다.

[UIView beginAnimations:@"SlideOut" context:nil];
[UIView setAnimationDuration:.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animateOut:finished:context:)];
CGRect frame = self.frame;
frame.origin.y = 480;
self.frame = frame;
[UIView commitAnimations];

으로, 히특은setAnimationDidStopSelectorCALayer에서 애니메이션을 위해 제가 원하는 것입니다.그런 것이 있습니까?

TIA.

CAT 트랜잭션을 사용할 수 있습니다. 완료 블록 처리기가 있습니다.

[CATransaction begin];
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
[pathAnimation setDuration:1];
[pathAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];    
[pathAnimation setToValue:[NSNumber numberWithFloat:1.0f]];
[CATransaction setCompletionBlock:^{_lastPoint = _currentPoint; _currentPoint = CGPointMake(_lastPoint.x + _wormStepHorizontalValue, _wormStepVerticalValue);}];
[_pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
[CATransaction commit];

저는 제 질문에 대답했습니다.다음을 사용하여 애니메이션을 추가해야 합니다.CABasicAnimation 예:

CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"frame"];
anim.fromValue = [NSValue valueWithCGRect:layer.frame];
anim.toValue = [NSValue valueWithCGRect:frame];
anim.delegate = self;
[layer addAnimation:anim forKey:@"frame"];

대리인 합니다.animationDidStop:finished:당신은 가도 좋습니다.이 기능이 존재해서 다행입니다! :D

2018년의 경우...

이보다 더 쉬운 일은 없습니다.

잊지 마세요.[weak self]그렇지 않으면 추락할 겁니다.

func animeExample() {
    
    CATransaction.begin()
    
    let a = CABasicAnimation(keyPath: "fillColor")
    a.fromValue, duration = ... etc etc
    
    CATransaction.setCompletionBlock{ [weak self] in
        self?.animeExample()
        self?.ringBell()
        print("again...")
    }
    
    someLayer.add(a, forKey: nil)
    CATransaction.commit()
}

중요 팁:

당신은 반드시setCompletionBlock 이전에someLayer.add.

주문이 중요합니다!이것은 iOS의 특이한 점입니다.

이 예에서, 그것은 단지 스스로를 다시 부를 뿐입니다.

물론, 어떤 기능이든 호출할 수 있습니다.


iOS 애니메이션을 처음 접하는 사람을 위한 참고 사항:

  1. "열쇠"(에 있는 것처럼)forKey)는 관련이 없으며 거의 사용되지 않습니다.0으로 설정합니다.설정하려면 "임의의 문자열"로 설정합니다.

  2. "keyPath"는 실제로 "당신이 애니메이션을 만들고 있는 것"입니다.문자 그대로 "불투명도", "배경색" 의 레이어 속성이지만 문자열작성됩니다. ("원하는 모든 항목"을 입력할 수는 없습니다. 레이어의 실제 속성 이름이어야 하며 애니메이션이 가능해야 합니다.)

반복: "키"(거의 사용되지 않음 - 0으로 설정)와 "keyPath"는 서로 전혀 관련이 없습니다.

종종 이 두 가지가 혼동되는 예제 코드를 볼 수 있으며(바보 같은 이름 덕분에), 이는 모든 종류의 문제를 야기합니다.


대신 대리인을 사용할 수 있지만 완료 블록을 사용하는 것이 훨씬 쉽습니다. (A) 이 블록은 자체적으로 포함되어 있고 어디서나 사용할 수 있고 (B) 보통 애니메이션이 두 개 이상 있기 때문입니다. (B) 대리인을 사용하는 것은 지루합니다.

다음은 bennythemink의 솔루션을 기반으로 한 Swift 3.0의 답변입니다.

    // Begin the transaction
    CATransaction.begin()
    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.duration = duration //duration is the number of seconds
    animation.fromValue = 0
    animation.toValue = 1
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    circleLayer.strokeEnd = 1.0

    // Callback function
    CATransaction.setCompletionBlock { 
        print("end animation")
    }

    // Do the actual animation and commit the transaction
    circleLayer.add(animation, forKey: "animateCircle")
    CATransaction.commit() 

이 쓰레기 때문에 4시간을 허비했어요 페이드 인 페이드 인 페이드 아웃을 하려고요코드의 주석을 메모합니다.

   [CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.duration = 0.3;
    animation.fromValue = [NSNumber numberWithFloat:0.0f];
    animation.toValue = [NSNumber numberWithFloat:1.0f];
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeBoth;
  ///  [box addAnimation:animation forKey:@"j"]; Animation will not work if added here. Need to add this only after the completion block.

    [CATransaction setCompletionBlock:^{

        CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation2.duration = 0.3;
        animation2.beginTime = CACurrentMediaTime()+1;
        animation2.fromValue = [NSNumber numberWithFloat:1.0f];
        animation2.toValue = [NSNumber numberWithFloat:0.0f];
        animation2.removedOnCompletion = NO;
        animation2.fillMode = kCAFillModeBoth;
        [box addAnimation:animation2 forKey:@"k"];

    }];

    [box addAnimation:animation forKey:@"j"];

    [CATransaction commit];

Google에서 이 페이지를 찾는 사용자를 위한 참고 사항:애니메이션 개체의 "위임자" 속성을 알림을 받을 개체로 설정하고 해당 개체의 .m 파일에 "애니메이션DidStop" 메서드를 구현하면 작업을 실제로 수행할 수 있습니다.방금 해봤는데 효과가 있어요.나는 왜 조 블로우가 그것이 올바른 방법이 아니라고 말했는지 모르겠습니다.

Swift 4+에서 방금 추가했습니다.delegate~하듯이

class CircleView: UIView,CAAnimationDelegate {
...

let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.delegate = self//Set delegate

애니메이션 완료 콜백 -

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
     print("Animation END")
  }

스위프트 5.0

func blinkShadow(completion: @escaping (() -> Void)) {
    CATransaction.begin()
    let animation = CABasicAnimation(keyPath: "shadowRadius")
    animation.fromValue = layer.shadowRadius
    animation.toValue = 0.0
    animation.duration = 0.1
    animation.autoreverses = true
    CATransaction.setCompletionBlock(completion)
    layer.add(animation, forKey: nil)
    CATransaction.commit()
}

CA Animation 객체를 설정할 때 지정된 애니메이션의 이름을 설정할 수 있습니다.애니메이션 DisStop:finished에서 애니메이션을 기반으로 특정 기능을 수행하기 위해 제공된 애니메이션 개체의 이름을 비교하기만 하면 됩니다.

2020년에는...

ValueAnimator, 사용자 지정 속성을 업데이트합니다.

https://github.com/Only-IceSoul/ios-jjvalueanimator

 class OnAnimationListener : AnimatorListener {

        weak var s : ViewController?

        init(_ ins: ViewController) {
            s = ins
        }
        func onAnimationStart(_ animation: Animator) {}
        func onAnimationEnd(_ animation: Animator) {

           print("end")
           s?.label.text = "end"

        }
        func onAnimationCancel(_ animation: Animator) {}
        func onAnimationRepeat(_ animation: Animator) {}

    }

저는 대리인을 구현하는 것에 싫증이 나서 CA 애니메이션에 대한 확장을 썼는데, 특히 대리인을 부르는 애니메이션을 보기 위해 애니메이션의 키를 사용하는 것과 같은 끔찍한 일을 해야 하는 여러 애니메이션에 대해서는 이것이 정말 쉬운 일이 됩니다.

깃허브에 있습니다 - 애니메이션 액션

누군가에게 유용하기를 바랍니다!

언급URL : https://stackoverflow.com/questions/296967/animation-end-callback-for-calayer

반응형