简体   繁体   中英

UIView animation block: if duration is 0, is it the same as without animation?

I need to handle a case where you can do something with or without animation, instead of:

if (animation)
{
    [UIView animateWithBlock:^(){...}];
}
else
{
    ...
}

I want to do:

[UIView animateWithBlock:^(){...} duration:(animation ? duration : 0)]

but not sure if it works, even if it does, is there any overhead for using this instead of directly change the view?

Thanks

What I do in this cases, is to create a block that contains all the animations I want to make. Then execute an UIView animation passing the animation block as a parameter, or directly calling that block, whether I want it to be animated or not. Something like this :

void (^animationBlock)();
animationBlock=^{
      // Your animation code goes here
};
if (animated) {
    [UIView animateWithDuration:0.3 animations:animationBlock completion:^(BOOL finished) {

    }];
}else{
    animationBlock();
}

That would avoid the overhead

According to the Apple docs:

If the duration of the animation is 0, this block is performed at the beginning of the next run loop cycle.

是的,由于持续时间为零,过渡将有效地瞬间完成。

I wrote this little Swift extension to overcome the issue:

extension UIView {

/// Does the same as animate(withDuration:animations:completion:), yet is snappier for duration 0
class func animateSnappily(withDuration duration: TimeInterval, animations: @escaping () -> Swift.Void, completion: (() -> Swift.Void)? = nil) {
    if duration == 0 {
        animations()
        completion?()
    }
    else {
        UIView.animate(withDuration: duration, animations: animations, completion: { _ in completion?() })
    }
}
}

One can use it as a replacement for UIView.animate(withDuration:animations:completion) and doesn't have to make any more thoughts about duration 0.

Okay, I have further observation on this. Firsth, there is a performance overhead when using the animation with zero duration but the more profound difference is that the animation's completion block is handled async. This means that first hiding and then displaying the view might not get you the result you expected.

So, no, I would definitely suggest not to use the zero as a duration as it's not synchronous.

you can set animateWithDuration value dynamically as per requirement.

If You set 0. it means no animation transition time.So, View will be appear without any animation. IF you want provide animation, set some value more than 0.

    **float animationDurationValue=0.03f;
        [UIView animateWithDuration:x delay:0.0f options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse 
animations:^{
                             [yourView setFrame:CGRectMake(0.0f, 100.0f, 300.0f, 200.0f)];
                         }
                         completion:nil];**

Please let me know if any issue.

As answered, it is not. Here is an example of how to do it in swift.

let setHighlighted: (Bool) -> Void = { [weak self] highlighted in
   if highlighted {
      self?.cardView.alpha = 0.6
   } else {
      self?.cardView.alpha = 1.0
   }
 }

 if animated {
    UIView.animate(withDuration: yourDuration) {
       setHighlighted(highlighted)
    }
 } else {
    setHighlighted(highlighted)
 }

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