ProgramingTip

CALayer에 대한 애니메이션 종료?

bestdevel 2020. 11. 12. 19:26
반응형

CALayer에 대한 애니메이션 종료?


CALayer의 애니메이션에 대한 집중이 어디에 있는지 궁금합니다. 특히, 프레임, 위치 등을 변경하는 것과 같은 묵시적 ​​애니메이션의 경우 UIView에서 다음과 같이 할 수 있습니다.

[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.


CATransaction을 사용할 수있는 완료 블록 처리기가 있습니다.

[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:잘 될 것입니다. 이 기능이 존재한다는 점에 감사드립니다! : 디


페이드 인 페이드 아웃을하기 위해이 쓰레기로 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];

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() 

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.

Google에서 이에 대한 자세한 내용을 읽을 수 있지만 일반적으로 순서대로 유지하는 것이 중요합니다. 이제 게시물로 돌아갑니다!

<<<<<참고-중요한 팁. . . . .

이 예에서는 자신을 다시 호출합니다.

물론 모든 함수를 호출 할 수 있습니다.


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

  1. "키"(에서와 같이 forKey)는 관련이 없으며 거의 ​​사용되지 않습니다 . nil로 설정하십시오. 설정하려면 "모든 문자열"로 설정하십시오.

  2. "keyPath"는 사실 실제 "애니메이션을 적용하는 것" 입니다. 말 그대로 "opacity", "backgroundColor"등과 같은 레이어속성 이지만 문자열로 작성됩니다 . (단순히 "원하는 모든 것"을 입력 할 수없고 레이어의 실제 속성 이름이어야하며 애니메이션이 가능해야합니다.)

반복하려면 : "key"(드물게 사용됨-그냥 nil로 설정)와 "keyPath"는 서로 전혀 관련이 없습니다.

이 두 가지가 어리석은 이름으로 인해 혼동 되는 예제 코드를 자주 볼 수 있으며 , 이는 모든 종류의 문제를 유발합니다.


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


Google에서이 페이지를 찾은 사용자를위한 참고 사항 : 애니메이션 개체의 "delegate"속성을 알림을받을 개체로 설정하고 해당 개체의 .m에서 "animationDidStop"메소드를 구현하여 작업을 완료 할 수 있습니다. 파일. 방금 시도했고 작동합니다. 왜 Joe Blow가 그것이 올바른 방법이 아니라고 말했는지 모르겠습니다.


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()
}

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

참고 URL : https://stackoverflow.com/questions/296967/animation-end-callback-for-calayer

반응형