简体   繁体   中英

How to interrupt UIView animation before completion?

I am using [UIView animateWithDuration... ] in order to display a text for each page of my app. Each page got its own text. I'm swiping to navigate between pages. I am using a 1 second dissolve effect to have the text fading in after the page is displayed.

Here's the problem: If I'm swiping during that 1 second (during which the text is fading in) the animation will complete when the next page appears and 2 texts will overlap (the previous and the current).

The solution I'd like to implement is to interrupt the animation if I happen to swipe during its occurrence. I just cannot make it happen. [self.view.layer removeAllAnimations]; does not work for me.

Here's my animation code:

   - (void) replaceContent: (UITextView *) theCurrentContent withContent: (UITextView *) theReplacementContent {

    theReplacementContent.alpha = 0.0;
    [self.view addSubview: theReplacementContent];


    theReplacementContent.alpha = 0.0;

    [UITextView animateWithDuration: 1.0
                              delay: 0.0
                            options: UIViewAnimationOptionTransitionCrossDissolve
                         animations: ^{
                             theCurrentContent.alpha = 0.0;
                             theReplacementContent.alpha = 1.0;
                         }
                         completion: ^(BOOL finished){
                             [theCurrentContent removeFromSuperview];
                             self.currentContent = theReplacementContent;
                             [self.view bringSubviewToFront:theReplacementContent];
                         }];

   }

Do you guys know how to make this work? Do you know any other way to address this issue?

You can not directly cancel animations created via +animateWithDuration... . What you want to do is replace the running animation with an instant new one.

You could write the following method, that get's called when you want to show the next page:

- (void)showNextPage
{
    //skip the running animation, if the animation is already finished, it does nothing
    [UIView animateWithDuration: 0.0
                          delay: 0.0
                        options: UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionBeginFromCurrentState
                     animations: ^{
                         theCurrentContent.alpha = 1.0;
                         theReplacementContent.alpha = 0.0;
                     }
                     completion: ^(BOOL finished){
                         theReplacementContent = ... // set the view for you next page
                         [self replaceContent:theCurrentContent withContent:theReplacementContent];
                     }];
}

Notice the additional UIViewAnimationOptionBeginFromCurrentState passed to options: . What this does is, it basically tells the framework to intercept any running animations for the affected properties and replace them with this one. By setting the duration: to 0.0 the new values are set instantly.

In the completion: block you can then create and set your new content and call your replaceContent:withContent: method.

So, another possible solution would be to just disable interaction during the animation.

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];

[[UIApplication sharedApplication] endIgnoringInteractionEvents];

I would declare a flag like shouldAllowContentToBeReplaced . Set it to false when the animation starts and back true when it's complete. Then say if (shouldAllowContentToBeReplaced) { before you start the animation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM