문제

취소 할 수 있습니까? UIView 진행중인 동안 애니메이션? 아니면 CA 레벨로 떨어 뜨려야합니까?

즉, 나는 이와 같은 일을했습니다 (아마도 최종 애니메이션 액션도 설정) :

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

그러나 애니메이션이 완료되고 애니메이션 종료 이벤트를 얻기 전에 취소하고 싶습니다 (짧게 잘라냅니다). 이게 가능해? 인터넷 검색은 몇몇 사람들이 답변없이 같은 질문을하는 것을 발견하고 한두 명의 사람들이 그것을 할 수 없다고 추측합니다.

도움이 되었습니까?

해결책

내가하는 방식은 엔드 포인트에 새로운 애니메이션을 만드는 것입니다. 매우 짧은 기간을 설정하고 사용하십시오. +setAnimationBeginsFromCurrentState: 현재 상태에서 시작하는 방법. 예로 설정하면 현재 애니메이션이 짧아집니다. 다음과 같이 보입니다.

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

다른 팁

사용:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];

중지하는 가장 간단한 방법 모두 특정 관점의 애니메이션, 즉시, 이건 :

프로젝트를 Quartzcore.framework에 연결하십시오. 코드 시작시 :

#import <QuartzCore/QuartzCore.h>

이제 트랙에서 죽은 뷰에서 모든 애니메이션을 중지하고 싶을 때 다음과 같이 말합니다.

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

중간 라인은 자체적으로 작동하지만 Runloop가 끝날 때까지 ( "Redraw Moment") 지연이 있습니다. 해당 지연을 방지하려면 표시된대로 명시 적 트랜잭션 블록으로 명령을 감싸십시오. 이 작업은 현재 런 루프 의이 레이어에서 다른 변경 사항이 수행되지 않은 경우에도 제공되지 않았습니다.

iOS 4 이상에서 사용 UIViewAnimationOptionBeginFromCurrentState 옵션 두 번째 애니메이션에서 첫 번째 애니메이션을 짧게 자릅니다.

예를 들어, 활동 표시기가있는보기가 있다고 가정하십시오. 잠재적으로 시간이 많이 걸리는 활동이 시작되는 동안 활동 지표에서 사라지고 활동이 완료되면 사라집니다. 아래 코드에서 활동 표시기가있는보기가 호출됩니다. activityView.

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}

애니메이션을 취소하려면 UIView 애니메이션 이외의 현재 애니메이션중인 속성을 설정하면됩니다. 그렇다면 애니메이션이 어디에 있든 애니메이션을 중지하고 UIView는 방금 정의한 설정으로 이동합니다.

이 답변을 부활 시키게되어 죄송하지만 iOS에서는 10 가지가 바뀌었고 이제 취소가 가능하며 우아하게 취소 할 수도 있습니다!

iOS 10 후에는 애니메이션을 취소 할 수 있습니다 uiviewpropertyanimator!

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

당신이 True를 통과하면 그것은 애니메이션을 취소하고 그것을 취소 한 곳에서 바로 중지됩니다. 완료 방법은 호출되지 않습니다. 그러나 허위를 전달하면 애니메이션을 완료 할 책임이 있습니다.

animator.finishAnimation(.start)

애니메이션을 마치고 현재 상태 (.Current)를 유지하거나 초기 상태 (.Start) 또는 종료 상태 (.end)로 이동할 수 있습니다.

그건 그렇고, 당신은 나중에 일시 중지하고 다시 시작할 수도 있습니다 ...

animator.pauseAnimation()
animator.startAnimation()

참고 : 갑작스런 취소를 원하지 않으면 애니메이션을 반전 시키거나 애니메이션을 일시 중지 한 후에도 변경할 수 있습니다!

보기 속성 대신 상수를 변경하여 제약 조건을 애니메이션하는 경우 다른 방법 중 어느 것도 iOS 8에서 작동하지 않습니다.

예제 애니메이션 :

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

해결책:

제약 조건 변경 및 하위 계층의 영향을받는 뷰의 레이어에서 애니메이션을 제거해야합니다.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}

매끄럽게 애니메이션을 일시 중지/중지하고 싶다면

self.yourView.layer.speed = 0;

원천: 레이어 트리의 애니메이션을 일시 중지하는 방법

위의 어느 것도 나를 위해 그것을 해결하지 못했지만 이것은 도움이되었습니다. UIView 애니메이션은 즉시 속성을 설정 한 다음 애니메이션을합니다. 프레젠테이션 레이어가 모델 (세트 속성)과 일치 할 때 애니메이션이 중지됩니다.

나는 내 문제를 해결했다. "나는 당신이 나타나는 것처럼 보이는 곳에서 애니메이션을하고 싶다"( '당신은보기를 의미한다). 당신이 그것을 원한다면 :

  1. 쿼츠 코어를 추가하십시오.
  2. CALayer * pLayer = theView.layer.presentationLayer;

프레젠테이션 레이어로 위치를 설정하십시오

나는 몇 가지 옵션을 사용합니다 UIViewAnimationOptionOverrideInheritedDuration

그러나 Apple의 문서는 모호하기 때문에 사용될 때 다른 애니메이션을 실제로 무시하는지 또는 타이머를 재설정하는지 모르겠습니다.

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

그리고 그것은 지금 당장 괜찮은 해결책이되어야합니다.

[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];

나도 같은 문제를 안고있어; API에는 특정 애니메이션을 취소 할 것이 없습니다. 그만큼

+ (void)setAnimationsEnabled:(BOOL)enabled

모든 애니메이션을 비활성화하므로 나에게 효과가 없습니다. 두 가지 해결책이 있습니다.

1) 애니메이션 객체를 하위 뷰로 만드십시오. 그런 다음 해당보기의 애니메이션을 취소하려면보기를 제거하거나 숨 깁니다. 매우 간단하지만 애니메이션을 보관 해야하는 경우 애니메이션없이 하위 뷰를 재현해야합니다.

2) 애니메이션 만 반복하고, 필요한 경우 애니메이션을 다시 시작하도록 대의원 선택기를 만들어 : 다음과 같이 필요합니다.

-(void) startAnimation {
NSLog(@"startAnim alpha:%f", self.alpha);
[self setAlpha:1.0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(pulseAnimationDidStop:finished:context:)];
[self setAlpha:0.1];
[UIView commitAnimations];
}

- (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if(hasFocus) {
    [self startAnimation];
} else {
    self.alpha = 1.0;
}
}

-(void) setHasFocus:(BOOL)_hasFocus {
hasFocus = _hasFocus;
if(hasFocus) {
    [self startAnimation];
}
}

2)의 문제는 현재 애니메이션주기가 끝날 때 애니메이션을 항상 지연시키는 것입니다.

도움이 되었기를 바랍니다.

애니메이션 위의 방식으로 애니메이션을 취소하더라도 didStopSelector 여전히 실행됩니다. 따라서 애플리케이션에 구동되는 응용 프로그램에 논리 상태가 있으면 문제가 발생합니다. 이러한 이유로 위에서 설명한 방식으로 나는 컨텍스트 변수를 사용합니다. UIView 애니메이션. 애니메이션이 애니메이션에 컨텍스트 매개 변수를 통해 프로그램의 현재 상태를 전달하는 경우 애니메이션이 중지 될 때 didStopSelector 함수는 현재 상태와 컨텍스트로 전달 된 상태 값을 기준으로 무언가를 해야하는지 또는 단지 반환할지 결정할 수 있습니다.

Stephen Darlington의 솔루션의 스위프트 버전

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];

상태를 원본 또는 최종으로 되 돌리지 않고 애니메이션을 일시 중지하려면 :

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;

내가 함께 일할 때 UIStackView 게다가 애니메이션 removeAllAnimations() 초기 값으로 설정해야합니다. removeAllAnimations() 예측할 수없는 상태로 설정할 수 있습니다. 나는 가지고있다 stackView ~와 함께 view1 그리고 view2 내부와 하나의보기가 보이고 숨겨져 있어야합니다.

public func configureStackView(hideView1: Bool, hideView2: Bool) {
    let oldHideView1 = view1.isHidden
    let oldHideView2 = view2.isHidden
    view1.layer.removeAllAnimations()
    view2.layer.removeAllAnimations()
    view.layer.removeAllAnimations()
    stackView.layer.removeAllAnimations()
    // after stopping animation the values are unpredictable, so set values to old
    view1.isHidden = oldHideView1 //    <- Solution is here
    view2.isHidden = oldHideView2 //    <- Solution is here

    UIView.animate(withDuration: 0.3,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                    view1.isHidden = hideView1
                    view2.isHidden = hideView2
                    stackView.layoutIfNeeded()
    },
                   completion: nil)
}

답변 된 솔루션 중 어느 것도 저에게 효과가 없었습니다. 나는이 문제를 해결했을 때 (이전 애니메이션이 아직 완료되지 않았을 때) 문제가 있었기 때문에 (올바른 방법인지 모르겠다). 나는 원하는 애니메이션을 통과합니다 CustomAnim 차단하다.

extension UIView
{

    func niceCustomTranstion(
        duration: CGFloat = 0.3,
        options: UIView.AnimationOptions = .transitionCrossDissolve,
        customAnim: @escaping () -> Void
        )
    {
        UIView.transition(
            with: self,
            duration: TimeInterval(duration),
            options: options,
            animations: {
                customAnim()
        },
            completion: { (finished) in
                if !finished
                {
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    self.layer.removeAllAnimations()
                    customAnim()
                }
        })

    }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top