2016-04-02 4 views
0

Ich bin eine UIViewController modal mit UIModalPresentationOverCurrentContext anzuzeigen, um eine Animation durchzuführen.Animation Abschluss Block vor dem Finish laufen?

[self presentViewController:messageVC animated:NO completion:^{ 
[messageVC displayMessageAutoReversed:YES withBlock:^(BOOL finished) { 
    if (finished) { 
     [messageVC dismissViewControllerAnimated:YES completion:nil]; 
    } 
}]; 
}]; 

innerhalb messageVC wird dieses Verfahren genannt:

-(void)displayMessageAutoReversed:(BOOL)autoReversed withBlock:(void (^)(BOOL finished))handler { 
    NSTimeInterval animationDuration = 0.4; 

    [UIView animateWithDuration:animationDuration delay:0 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{ 

     self.visualEffectView.effect = [UIBlurEffect effectWithStyle:self.blurEffectStyle]; 
     self.messageLabel.alpha = 1.0f; 
     self.imageView.alpha = 1.0f; 

    }completion:^(BOOL finished) { 
     if (finished) 
     { 
      if (autoReversed) 
      { 
       [self hideMessageWithBlock:^(BOOL finished) { 
        if (handler) { handler(finished); } 
       }]; 
      } else 
      { 
       if (handler) { handler(finished); } 
      } 
     } 
    }]; 
} 

-(void)hideMessageWithBlock:(void (^)(BOOL finished))handler { 
    NSTimeInterval animationDuration = 0.4; 

    [UIView animateWithDuration:animationDuration delay:animationDuration + 1.5 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{ 

     self.visualEffectView.effect = nil; 
     self.messageLabel.alpha = 0.0f; 
     self.imageView.alpha = 0.0f; 

    }completion:^(BOOL finished) { 
     if (handler) { handler(finished); } 
    }]; 
} 

aber die Animation Block innerhalb hideMessageWithBlock wird sofort aufgerufen, anstatt nach der 1,9 Sekunden Verzögerung - die die Wirkung auf Null setzt, bevor es plötzlich springt zurück zu verschwommen. Warum ist das? Es flimmert zu nil und springt dann zurück zu verschwommen, bevor es nach einer weiteren Sekunde korrekt ausblendet.

Edit:

double delayInSeconds = 2.0; 
dispatch_time_t reverseTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(reverseTime, dispatch_get_main_queue(), ^(void) { 
    /* put whole animation block here? */ 
}); 
+0

Ich bin mir nicht sicher, 'visualEffectView' Animation wird mit Federanimation arbeiten. – Sulthan

+0

@sulthan hmm, komisch. Es muss gut funktionieren, wenn man bedenkt, dass es mit Ausnahme des Flimmerns korrekt animiert wird. – Erik

+0

@ Paulw11 scheint plausibel, aber wie kann man die Unschärfe vollständig transparent machen/animieren, indem man nil einstellt, wenn sie nicht animierbar ist? - Wie es in der Tat animiert ist, nur eine Sekunde oder zwei nach dem Flimmern – Erik

Antwort

0

Ich vermute, dass die UIView Animation Methoden tatsächlich den Block sofort ausführen, um die animierbaren Eigenschaften zu bestimmen, die geändert werden, und somit Ihre optische Wirkung im Hinblick auf Null wird eingestellt sofort, da das keine animierbare Eigenschaft ist.

Anstatt animateWithDuration:animationDuration delay:... zu verwenden, können Sie eine einfache animateWithDuration verwenden und dispatch_after verwenden, um die Animation zu verzögern.

double delayInSeconds = 1.9; 
dispatch_time_t reverseTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(reverseTime, dispatch_get_main_queue(), ^(void) { 
    [UIView animateWithDuration:animationDuration delay:0 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{ 

     self.visualEffectView.effect = nil; 
     self.messageLabel.alpha = 0.0f; 
     self.imageView.alpha = 0.0f; 

    }completion:^(BOOL finished) { 
     if (handler) { handler(finished); } 
    }]; 
}); 
Verwandte Themen