如何在更改uiview隐藏模式的同时添加animation?

我想添加animation到一个视图,而改变其隐藏模式即

my_view.hidden=YES; 

我在导航栏中添加了一个button。 当我们点击它时,新视图被设置为取消隐藏。 它在导航表的上部绘制。

不幸的是,隐藏不是通过UIViewanimation可以animation的属性。 我认为你最好的select可能是使用@Erik Bbuild议的animation之一,或者开始涉猎更强大的核心animation。 看一看UIViewanimation和核心animation的文档。

我通过使用UIViewanimation从另一个视图下方滑动新视图来达到类似于您的build议的效果。 这使得它看起来像一个抽屉滑出。 如果你想做这样的事情,你需要拦截里面的事件,并把animation代码放在那里。

 - (IBAction)buttonClicked:(id)sender { [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationCurveEaseOut animations:^(void) { self.myView.frame = /* set the frame here */ } completion:NULL]; } 

将视图的不透明度从100%animation化为0%。 有animation完成callback设置视图隐藏。 您可能还希望在callback过程中将不透明度重置为100%,因此取消隐藏时视图将显示为完全不透明。

 yourView.alpha = 0.0 //for zero opacity yourView.alpha = 1.0 //for 100% opacity 

没有隐藏的animation, 你用下面的Swift代码得到相同的结果:

 UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: { self.yourView.alpha = 0 // Here you will get the animation you want }, completion: { _ in self.yourView.hidden = true // Here you hide it when animation done }) 

下面是我写的一个类,它介绍了一个新的“隐藏”属性在UIView正确支持animation:

 @implementation UIView (AnimateHidden) -(void)setHiddenAnimated:(BOOL)hide { [UIView animateWithDuration:0.5 delay:0.0 options: UIViewAnimationCurveEaseOut animations:^ { [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; if (hide) self.alpha=0; else { self.hidden= NO; self.alpha=1; } } completion:^(BOOL b) { if (hide) self.hidden= YES; } ]; } @end 

我认为更合适的做法是:

 [UIView transitionWithView:aView duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){ aView.hidden = NO; } completion:nil]; 

更新到Swift 3

 UIView.animate(withDuration: 0.2, delay: 0.2, options: .curveEaseOut, animations: {firstView.alpha = 0}, completion: { _ in firstView.isHidden = true //Do anything else that depends on this animation ending }) 

如果您希望在第一个视图消失之后重新创buildanimation,则可以使用alpha = 1hidden = false复制完成块内的代码。

这是更正的NJ版本:

 @implementation UIView (AnimateHidden) -(void)setHiddenAnimated:(BOOL)hide duration:(NSTimeInterval)duration { if(self.hidden == hide) return; if(hide) self.alpha = 1; else { self.alpha = 0; self.hidden = NO; } [UIView animateWithDuration:duration animations:^{ if (hide) self.alpha = 0; else self.alpha = 1; } completion:^(BOOL finished) { if(finished) self.hidden = hide; }]; } @end 

这里是快速的版本:

  UIView.animateWithDuration(0.5, delay: 0.2, options: UIViewAnimationOptions.CurveEaseOut, animations: { objView.alpha = 0 }, completion: { finished in objView.hidden = true }) 

这将执行animation持续5秒和延迟2秒后。

可用的AnimationOptions是:

 CurveEaseInOut, CurveEaseIn, CurveEaseOut, CurveLinear 

新泽西州和斯坦尼斯拉夫的答案在这里帮助我做了一个新的类别,我认为这改善了他们的答案,所以以为我会张贴我想出来的情况下,以帮助其他人。

请注意,它只能在iOS4或更高版本中使用,因为它使用的是块。

UIView的+ AnimateHidden.m

 #import "UIView+AnimateHidden.h" @implementation UIView (AnimateHidden) - (void)setHidden:(BOOL)hidden animated:(BOOL)animated { // If the hidden value is already set, do nothing if (hidden == self.hidden) { return; } // If no animation requested, do the normal setHidden method else if (animated == NO) { [self setHidden:hidden]; return; } else { // Store the view's current alpha value CGFloat origAlpha = self.alpha; // If we're unhiding the view, make it invisible initially if (hidden == NO) { self.alpha = 0; } // Unhide the view so we can see the animation self.hidden = NO; // Do the animation [UIView animateWithDuration:0.5 delay:0.0 options: UIViewAnimationOptionCurveEaseOut animations:^{ // Start animation block if (hidden == YES) { self.alpha = 0; } else { self.alpha = origAlpha; } // End animation block } completion:^(BOOL b){ // Start completion block // Finish up by hiding the view if necessary... self.hidden = hidden; // ... and putting back the correct alpha value self.alpha = origAlpha; // End completion block }]; } } @end 

由于这些答案中的一些有点混乱,我想我可以发布我的这个API的简约devise。 我还增加了延迟和持续时间 – 因为为什么不。

在我们的实施中。

 #import "UIView+AnimateHidden.h" @implementation UIView (AnimateHidden) - (void)setHiddenAnimated:(BOOL)hide delay:(NSTimeInterval)delay duration:(NSTimeInterval)duration { [UIView animateWithDuration:duration delay:delay options:UIViewAnimationOptionAllowAnimatedContent animations:^{ if (hide) { self.alpha = 0; } else { self.alpha = 0; self.hidden = NO; // We need this to see the animation 0 -> 1 self.alpha = 1; } } completion:^(BOOL finished) { self.hidden = hide; }]; } @end 

在我们的文件中。

 #import <UIKit/UIKit.h> @interface UIView (AnimateHidden) - (void)setHiddenAnimated:(BOOL)hide delay:(NSTimeInterval)delay duration:(NSTimeInterval)duration; @end 

另一个版本,如果你想使用更复杂的animationtypes或UIView不支持的animation

 - (void)setHidden:(BOOL)hidden withAnimationDuration:(NSTimeInterval)duration { CATransition* transition = ({ CATransition* its = [CATransition animation]; its.duration = duration; its.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; its.type = kCATransitionPush; its.subtype = (hidden ? @"fromBottom" : @"fromTop"); its }); UIView* containerView = self.superview; [containerView.layer removeAllAnimations]; [containerView.layer addAnimation: transition forKey: kCATransition]; self.hidden = hidden; if (!hidden) { [self.superview bringSubviewToFront: self]; } } 

这里是我用来模拟一个“显示更多…”和“显示更less…”button点击“增长”和“收缩”的代码。 模仿Palyancodr的答案

这种方法允许我在故事板中创build两个视图,以使约束在不同的iOS设备上按预期工作,并且我不需要自定义代码所有约束。

 @IBAction func showMoreOrLessAction(_ sender: Any) { // if small view showing if showMoreLargeView.isHidden { showMoreSmallView.isHidden = true //showMoreLargeView.isHidden = false UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: { self.showMoreLargeView.alpha = 1 // Here you will get the animation you want }, completion: { _ in self.showMoreLargeView.isHidden = false // Here you hide it when animation done }) } else { // large view showing //showMoreSmallView.isHidden = false UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: { self.showMoreSmallView.alpha = 1 // Here you will get the animation you want }, completion: { _ in self.showMoreSmallView.isHidden = false // Here you hide it when animation done }) showMoreLargeView.isHidden = true } }