如何在更改uiview的隐藏模式时添加动画?

问题描述

| 我想在更改其隐藏模式的同时向视图添加动画,即
my_view.hidden=YES;
我在导航栏中添加一个按钮。当我们单击它时,新视图设置为取消隐藏。它绘制在导航表的上方。     

解决方法

        不幸的是,hidden不是可以通过UIView动画设置动画的属性。我认为您最好的选择可能是使用@Erik B建议的动画之一,或者开始尝试功能更强大的Core Animations。浏览一下UIView动画和Core动画的文档。 通过使用UIView动画从另一个视图下面滑动新视图,我达到了您的建议。这使它看起来像抽屉一样滑出。如果要执行类似的操作,则需要拦截事件内部的补齐并将动画代码放在此处。
- (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%设置为0%。让动画完成回调将视图设置为隐藏。您可能还希望在回调期间将不透明度重新设置为100%,因此取消隐藏时视图将显示为完全不透明。
yourView.alpha = 0.0 //for zero opacity
yourView.alpha = 1.0 //for 100% opacity
    ,        但是没有隐藏的动画。使用以下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 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
    })
而且,如果您希望在第一个视图消失后重新制作动画,则可以使用
alpha = 1
hidden = false
复制完成块内的代码。     ,        这是我写的一个类别,目的是在UIView上引入一个新的“ hidden \”属性,该属性正确支持动画:
@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
    ,        已更正为新泽西州版本:
@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,options:
    UIViewAnimationOptions.CurveEaseOut,animations: {
            objView.alpha = 0
        },completion: { finished in
            objView.hidden = true
  })
这将以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的简约设计。我还添加了延迟和持续时间-为什么不这样做。 在实现中,我们有。
#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
    ,        如果您希望使用更复杂的动画类型或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];
    }
}
    ,        这是我用来在“显示更多... \”和“显示较少... \”按钮单击时对视图“增长”和“收缩”建模的代码。模仿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,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,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
    }
}