ProgramingTip

Objective-C- 애니메이션 후 변경 사항을 적용하는 CABasicAnimation?

bestdevel 2020. 12. 2. 21:42
반응형

Objective-C- 애니메이션 후 변경 사항을 적용하는 CABasicAnimation?


CABasicAnimation이미지보기를 이동하고 크기를 조정하는 데 사용 하고 있습니다. 이미지보기를 수퍼 뷰에 추가하고 애니메이션 한 다음 수퍼 뷰에서 제거하고 싶습니다.

이를 달성하기 위해 내 델리게이트 호출을 듣고 호출 CAAnimationGroup되는 즉시 수퍼 뷰에서 이미지 뷰를 제거합니다.

문제는 전에 이미지가 수퍼 뷰에서 초기 위치에서 깜박이는 것입니다. 이 동작을 피하는 가장 좋은 방법은 무엇입니까?

CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, opacityAnim, nil];
    animGroup.duration = .5;
    animGroup.delegate = self;
    [imageView.layer addAnimation:animGroup forKey:nil];

레이어에 애니메이션을 추가해도 애니메이션은 레이어의 속성을 변경하지 않습니다. 대신 시스템에서 레이어의 복사본을 만듭니다. 원본 레이어를 모델 레이어라고하고 복제 레이어를 프레젠테이션 레이어합니다. 프레젠테이션 레이어의 속성은 애니메이션이 진행됨에 따라 변경된 모델 레이어의 속성은 변경되지 않습니다.

애니메이션을 제거하면 시스템은 프레젠테이션 레이어를 파괴하고 모델 레이어 만 다리 모델 레이어의 속성에 따라 레이어가 그려지는 방식을 제어합니다. 따라서 모델 레이어의 속성이 프레젠테이션 레이어 속성의 최종 애니메이션 값과 일치하지 않는 레이어가 애니메이션 이전의 모양으로 즉시 나타납니다.

이를 수정하여 광고 모델 레이어의 속성을 애니메이션의 최종 값으로 설정 한 다음 레이어에 애니메이션을 추가해야합니다. 레이어 속성을 변경하면 추가 속성에 대한 암시 적 애니메이션이 추가되어 명시 적으로 추가하려는 애니메이션과 충돌 할 수 있으므로 순서대로 수행 할 수 있습니다. 명시 적 애니메이션이 암시 적 애니메이션을 재정의하는지 확인합니다.

그래서이 모든 것을 어떻게 처리합니까? 기본 레시피는 다음과 가변합니다.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:myLayer.position];
layer.position = newPosition; // HERE I UPDATE THE MODEL LAYER'S PROPERTY
animation.toValue = [NSValue valueWithCGPoint:myLayer.position];
animation.duration = .5;
[myLayer addAnimation:animation forKey:animation.keyPath];

애니메이션 그룹을 사용하지 않을 경우 어떤 것을 변경 해야할지 알 수 없습니다. 각 애니메이션을 레이어에 추가합니다.

또한 애니메이션 대리 +[CATransaction setCompletionBlock:]튼 사용하는 대신 방법을 사용하여 하나 또는 여러 애니메이션에 대한 완료 처리기를 설정하는 것이 더 많은 것을 알았습니다 . 트랜잭션의 완료 블록을 설정 한 다음 애니메이션을 추가합니다.

[CATransaction begin]; {
    [CATransaction setCompletionBlock:^{
        [self.imageView removeFromSuperview];
    }];
    [self addPositionAnimation];
    [self addScaleAnimation];
    [self addOpacityAnimation];
} [CATransaction commit];

CAAnimations는 완료되면 자동으로 제거됩니다. removedOnCompletion관리자 제어는 속성 이 있습니다. 로 설정해야합니다

NO.

또한 fillMode애니메이션의 지속 시간 전후에 애니메이션의 동작을 제어하는 기기가 있습니다 . 이것은 선언 된 속성입니다 CAMediaTiming( 준수 CAAnimation). 담당자로 설정해야합니다 kCAFillModeForwards.

이 두 가지 변경으로 애니메이션은 계속 지속되어야합니다. 그러나 그룹 내에서 변경해야 할 것인지, 그룹 내의 식별 애니메이션에서 변경해야 할 것인지 또는 둘 다에서 변경해야 할 것인지.


누군가에게 도움이 될 수있는 Swift의 예입니다.

그래디언트 레이어의 애니메이션입니다. .locations속성을 애니메이션하고 있습니다.

@robMayoff 완전히 완전히 설명하는 중요한 점은 다음과 가변적입니다.

놀랍게도 레이어 애니메이션을 할 때 실제로 애니메이션을 시작하기 전에 최종 값을 먼저 설정합니다!

다음은 애니메이션이 끝없이 반복되기 때문에 좋은 예입니다.

애니메이션이 끝없이 반복 될 때 "애니메이션을 적용하기 전에 값을 설정하는 것을 잊어 버림"이라는 고전적인 실수를 범하면 애니메이션 사이에 "깜박임"이 가끔 나타납니다.

var previousLocations: [NSNumber] = []
...

func flexTheColors() { // "flex" the color bands randomly

    let oldValues = previousTargetLocations
    let newValues = randomLocations()
    previousTargetLocations = newValues

    // IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
    theLayer.locations = newValues

    // AND NOW ANIMATE:
    CATransaction.begin()

    // and by the way, this is how you endlessly animate:
    CATransaction.setCompletionBlock{ [weak self] in
        if self == nil { return }
        self?.animeFlexColorsEndless()
    }

    let a = CABasicAnimation(keyPath: "locations")
    a.isCumulative = false
    a.autoreverses = false
    a.isRemovedOnCompletion = true
    a.repeatCount = 0

    a.fromValue = oldValues
    a.toValue = newValues

    a.duration = (2.0...4.0).random()

    theLayer.add(a, forKey: nil)
    CATransaction.commit()
}

다음은 새로운 프로그래머를위한 내용을 명확히하는 데 도움이 될 수 있습니다. 내 코드에서 다음을 수행합니다.

    // IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
    theLayer.locations = newValues

    // AND NOW ANIMATE:
    CATransaction.begin()
    ...set up the animation...
    CATransaction.commit()

그러나 다른 답변의 코드 예제에서는 다음과 같습니다.

    CATransaction.begin()
    ...set up the animation...
    // IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
    theLayer.locations = newValues
    CATransaction.commit()

"애니메이션을 적용하기 전에 값을 설정"하는 코드 줄의 위치에 대해 ..

실제로 그 줄 이 시작-커밋 코드 줄 "내부" 에있는 것은 실제로 완벽하게 괜찮습니다 . 너무 오래 당신이 전에처럼 .commit().

나는 새로운 애니메이터를 혼동 할 수 있기 때문에 이것을 언급 할뿐입니다.

참고 URL : https://stackoverflow.com/questions/11515647/objective-c-cabasicanimation-applying-changes-after-animation

반응형