【问题标题】:How to add animation while changing the hidden mode of a uiview?如何在更改uiview的隐藏模式时添加动画?
【发布时间】:2011-09-04 20:45:12
【问题描述】:

我想在更改其隐藏模式时向视图添加动画,即

my_view.hidden=YES;

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

【问题讨论】:

  • 你想要什么样的动画,例如淡入淡出、翻转等?

标签: ios animation button uiview navigationbar


【解决方案1】:

将视图的不透明度从 100% 设置为 0%。让动画完成回调将视图设置为隐藏。您可能还希望在回调期间将不透明度重置为 100%,以便在取消隐藏时视图将显示为完全不透明。

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

【讨论】:

  • 如果 w 在此之前需要使用 alpha,为什么要隐藏呢?使用 alpha 会降低性能,我们不会使用这种方法来避免这种情况。
【解决方案2】:

但是没有隐藏动画;使用下面的 Swift 代码可以得到相同的结果:

UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {            
    self.yourView.alpha = 0 // Here you can change the alpha property of the view 
}, completion: { _ in  
    self.yourView.isHidden = true // Here you hide it when animation done
})

【讨论】:

  • 太棒了,简单。谢谢!
  • 出现错误:nil 与预期的参数类型“UIViewAnimationOptions”不兼容。我正在使用 Xcode 7.3.1。
  • @JayprakashDubey 你可以用options: []替换options: nil
  • 这可能应该是选择的答案(实际上可能不是因为 OP 在 Obj-C 时代发布了这个),这很简洁,完全符合 OP/我自己的需要
【解决方案3】:

不幸的是,hidden 不是一个可以通过 UIView 动画设置动画的属性。我认为你最好的选择可能是使用@Erik B 建议的动画之一,或者开始涉足更强大的核心动画。浏览一下 UIView 动画和核心动画的文档。

通过使用 UIView 动画从另一个视图下方滑动新视图,我实现了类似于您的建议。这使它看起来像一个滑出的抽屉。如果你想做这样的事情,你需要拦截 touch up inside 事件并将动画代码放在那里。

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

【讨论】:

  • 选项应该是:UIViewAnimationOptionCurveEaseInOut
【解决方案4】:

我认为更合适的做法是:

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

【讨论】:

  • 这是正确答案,不需要弄乱 alpha。我已经把它整理好了,这样更清晰。
【解决方案5】:

更新到 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
    })

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

【讨论】:

    【解决方案6】:

    这是我写的一个类别,用于在 UIView 上引入一个新的“隐藏”属性,它正确支持动画:

    @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
    

    【讨论】:

    • 谢谢,这对我有用!但我做了一些补充以使其与hidden 属性互操作:基本上,始终将alpha 保留在最后的1.0,结束设置正确的起始alphahidden
    【解决方案7】:

    这是更正的 N.J. 版本:

    @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
    

    【讨论】:

      【解决方案8】:

      这是 swift 版本:

      斯威夫特 2

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

      斯威夫特 3、4、5

      UIView.animate(withDuration: 0.5, delay: 0.2, options: UIView.AnimationOptions.curveEaseOut, animations: {
          objView.alpha = 0
      }, completion: { finished in
          objView.isHidden = true
      })
      

      这将执行持续时间为 5 秒并延迟 2 秒后的动画。

      可用的动画选项是:

      CurveEaseInOut, CurveEaseIn, CurveEaseOut, CurveLinear
      

      【讨论】:

        【解决方案9】:

        由于其中一些答案有点混乱,我想我可以发布我对该 API 的简约设计。我还添加了延迟和持续时间 - 为什么不呢。

        在我们的实现中。

        #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
        

        在我们的 header 文件中。

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

        【讨论】:

          【解决方案10】:

          NJ 和 Stanislav 的答案在这里帮助我为此创建了一个新类别,我认为这改进了他们的答案,所以我想我会发布我想出的东西以防它帮助其他人。

          请注意,它仅在 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
          

          【讨论】:

          • 查看 Abhi 对新 API 的回答,它使这变得更简单,无需触及 alpha 值。
          【解决方案11】:

          如果您希望使用更复杂的动画类型或 UIView 不支持的动画,则可以使用另一个版本

          - (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];
              }
          }
          

          【讨论】:

            【解决方案12】:

            这是我用来在“显示更多...”和“显示更少...”按钮单击时为视图“增长”和“缩小”建模的代码。模仿 Palyancodr 的答案

            这种方法允许我在故事板中创建两个视图,以便约束在不同的 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
                }
            }
            

            【讨论】:

              猜你喜欢
              • 2012-09-03
              • 1970-01-01
              • 2019-08-30
              • 2012-02-25
              • 2021-05-24
              • 1970-01-01
              • 2011-01-26
              • 1970-01-01
              • 2021-04-24
              相关资源
              最近更新 更多