iOS—— UIView 动画

27 篇文章 0 订阅

UIView动画

  1. UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持,执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之间
  2. UIView本身对于基本动画和关键帧动画、转场动画都有相应的封装,在对动画细节没有特殊要求的情况下使用起来也要简单的多。可以说在日常开发中90%以上的情况使用UIView的动画封装方法都可以搞定。

  3. 支持动画的属性有:frame 、center、bounds、alpha、transform
    UIView’动画也支持翻转或者翻页效果: UIView AnimationTransitionxxx

  4. UIView封装的动画与CALayer动画的对比
    使用UIView和CALayer都能实现动画效果,但是在真实的开发中,一般还是主要使用UIView封装的动画,而很少使用CALayer的动画。

  5. CALayer核心动画与UIView动画的区别:
    UIView封装的动画执行完毕之后不会反弹。即如果是通过CALayer核心动画改变layer的位置状态,表面上看虽然已经改变了,但是实际上它的位置是没有改变的。

一 .基础动画

- (void)viewDidLoad {
    [super viewDidLoad];

   // 设置背景
    UIImage *backgroundImage = [UIImage imageNamed:@"image"];
    self.view.backgroundColor = [UIColor colorWithPatternImage:backgroundImage];

    // 创建图像显示控件
    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1"]];
    self.imageView.frame = CGRectMake(0, 0, 150, 150);
    self.imageView.center = CGPointMake(50, 150);
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch * touch = touches.anyObject;
    CGPoint  location = [touch locationInView:self.view];
#pragma mark 基础动画
    // 方法一  1. block 动画
    /*开始动画,UIView的动画方法执行完后动画会停留在重点位置,而不需要进行任何特殊处理
     duration:执行时间
     delay:延迟时间
     options:动画设置,例如自动恢复、匀速运动等
     completion:动画完成回调方法
     */
   [UIView animateWithDuration:3.0 delay:0.0 options:(UIViewAnimationOptionAllowUserInteraction) animations:^{

       self.imageView.center = location;
   } completion:^(BOOL finished) {
       NSLog(@"Animation end");
   }];

    // 方法2 ,静态方法(不是用block)
    // 开始动画,
    // + (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context;
    // animationID 动画识别作用。 context  上下文,传进去什么返回什么。
    [UIView beginAnimations:@"firstAnimation" context:@"1243ji"];
    // 动画时间
    [UIView setAnimationDuration:2.0];
    // 设置延迟
    [UIView setAnimationDelay:0.0];
    // 自动返回 (设置为YES 后自动返回。动画的方式返回)不管是否自动返回,最后结束都是修改后的位置(对应UIView 动画改变是真正改变)如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
    [UIView setAnimationRepeatAutoreverses:YES];
    // 重复次数
    [UIView setAnimationRepeatCount:2];
    // 渐变效果 (动画逐渐变慢)
   [UIView setAnimationCurve:(UIViewAnimationCurveEaseIn)];

    // 设置代理
    [UIView setAnimationDelegate:self];
    // 动画开始时执行的方法(如果不设置会有默认方法)
    [UIView setAnimationWillStartSelector:@selector(beginAnimations)];
    // 动画结束时执行的方法(如果不设置会有默认方法)
    [UIView setAnimationDidStopSelector:@selector(didEndAnimation)];

    // 动画要实现的效果
    self.imageView.center = location;
    // 结束动画
    [UIView commitAnimations];
// 设置之后不再执行默认的动画开始结束方法,而是执行下面方法
- (void)beginAnimations
{
    NSLog(@"Begin Animation");
}
- (void)didEndAnimation
{
    NSLog(@"End Animation");
}


//  动画开始执行的方法(setAnimationWillStartSelector)不设置,就会执行下面的方法, 这里的animationID 用来区分Animation的ID。 context 就是初始化事设置context。
- (void)animationWillStart:(NSString *)animationID context:(void *)context
{
    NSLog(@"%@",context);
}
//  动画结束执行的方法 ,同上
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    NSLog(@"%@",context);
}

补充: 弹簧效果动画

#pragma mark 弹性动画
    /*创建弹性动画
     damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显
     velocity:弹性复位的速度
     */
    [UIView animateWithDuration:3.0 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:1.0 options:(UIViewAnimationOptionCurveEaseIn) animations:^{
        self.imageView.center = location;
    } completion:^(BOOL finished) {
        NSLog(@"Animation End");
    }];

这里写图片描述
补充–动画设置参数

在动画方法中有一个option参数,UIViewAnimationOptions类型,它是一个枚举类型,动画参数分为三类,可以组合使用:

1.常规动画属性设置(可以同时选择多个进行设置)

UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat:重复运行动画。
UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。
UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意仅仅适用于转场动画)。 
UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)
UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。

2.动画速度控制(可从其中选择一个设置)

UIViewAnimationOptionCurveEaseInOut:动画先缓慢,然后逐渐加速。
UIViewAnimationOptionCurveEaseIn :动画逐渐变慢。
UIViewAnimationOptionCurveEaseOut:动画逐渐加速。
UIViewAnimationOptionCurveLinear :动画匀速执行,默认值。

二. 关键帧动画

@interface ViewAnimationViewController ()
@property (nonatomic, strong) UIImageView * imageView;
@end
@implementation ViewAnimationViewController

- (void)viewDidLoad {
    [super viewDidLoad];

   // 设置背景
    UIImage *backgroundImage = [UIImage imageNamed:@"image"];
    self.view.backgroundColor = [UIColor colorWithPatternImage:backgroundImage];

    // 创建图像显示控件
    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1"]];
    self.imageView.frame = CGRectMake(0, 0, 150, 150);
    self.imageView.center = CGPointMake(50, 150);
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch * touch = touches.anyObject;
    CGPoint  location = [touch locationInView:self.view];

#pragma mark 关键帧动画
    [UIView animateKeyframesWithDuration:5.0 delay:0 options:(UIViewKeyframeAnimationOptionCalculationModeLinear) animations:^{
        //第二个关键帧(准确的说第一个关键帧是开始位置):从0秒开始持续50%的时间,也就是5.0*0.5=2.5秒
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
            self.imageView.center = CGPointMake(50, 200);
        }];
         //第三个关键帧,从0.5*5.0秒开始,持续5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{
            self.imageView.center = CGPointMake(50, 250);
        }];
        //第四个关键帧:从0.75*5.0秒开始,持所需5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
            self.imageView.center = CGPointMake(50, 300);
        }];

    } completion:^(BOOL finished) {

        NSLog(@"Animation END");
    }];
}

UIImageView 的帧动画
1.UIImageView的帧动画

UIImageView可以让一系列的图片在特定的时间内按顺序显示

相关属性解析:
animationImages:要显示的图片(一个装着UIImage的NSArray)
animationDuration:完整地显示一次animationImages中的所有图片所需的时间
animationRepeatCount:动画的执行次数(默认为0,代表无限循环)
相关方法解析:
- (void)startAnimating; 开始动画
- (void)stopAnimating;  停止动画
- (BOOL)isAnimating;  是否正在运行动画

2.UIActivityIndicatorView

是一个旋转进度轮,可以用来告知用户有一个操作正在进行中,一般用initWithActivityIndicatorStyle初始化

方法解析:
- (void)startAnimating; 开始动画
- (void)stopAnimating;  停止动画
- (BOOL)isAnimating;  是否正在运行动画
UIActivityIndicatorViewStyle有3个值可供选择:
UIActivityIndicatorViewStyleWhiteLarge   //大型白色指示器    
UIActivityIndicatorViewStyleWhite      //标准尺寸白色指示器    
UIActivityIndicatorViewStyleGray    //灰色指示器,用于白色背景

补充–动画设置参数

对于关键帧动画也有一些动画参数设置options,UIViewKeyframeAnimationOptions类型,和上面基本动画参数设置有些差别,关键帧动画设置参数分为两类,可以组合使用:

1.常规动画属性设置(可以同时选择多个进行设置)

UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat:重复运行动画。
UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。

2.动画模式设置(同前面关键帧动画动画模式一一对应,可以从其中选择一个进行设置)

UIViewKeyframeAnimationOptionCalculationModeLinear:连续运算模式。
UIViewKeyframeAnimationOptionCalculationModeDiscrete :离散运算模式。
UIViewKeyframeAnimationOptionCalculationModePaced:均匀执行运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubic:平滑运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubicPaced:平滑均匀运算模式。

注意:关键帧动画有两种形式,上面演示的是属性值关键帧动画,路径关键帧动画目前UIView还不支持。

三 . 转场动画 (Block)
1.

+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

参数解析:
duration:动画的持续时间
view:需要进行转场动画的视图
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block

2.

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion

方法调用完毕后,相当于执行了下面两句代码:
// 添加toView到父视图
[fromView.superview addSubview:toView];
// 把fromView从父视图中移除
[fromView.superview removeFromSuperview];
参数解析:
duration:动画的持续时间
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block

option 参数

转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置)
UIViewAnimationOptionTransitionNone:没有转场动画效果。
UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。
UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。
UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。   
UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。   
UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。   
UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。   
UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果。

代码

@interface ViewAnimationSecondViewController ()
{
    NSInteger _currentIndex; // 当前图片的Index
}
@property (nonatomic, strong) UIImageView * imageView;
@end

@implementation ViewAnimationSecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _currentIndex = 1;
    self.imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"image0"]];
    self.imageView.frame = [UIScreen mainScreen].bounds;
    [self.view addSubview:self.imageView];

    // 添加手势 (轻扫)
    UISwipeGestureRecognizer * leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(leftSwipeGesture:)];
    leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:leftSwipeGesture];

    UISwipeGestureRecognizer * rightSwipGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipGesture:)];
    rightSwipGesture.direction = UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:rightSwipGesture];
}

#pragma mark 左划浏览下一张图片
- (void)leftSwipeGesture:(UISwipeGestureRecognizer *)gesture
{
    [self transitionAnimation:YES];
}
#pragma mark 右划浏览上一张图片
- (void)rightSwipGesture:(UISwipeGestureRecognizer *)gesture
{
    [self transitionAnimation:NO];
}

#pragma mark 转场动画
- (void)transitionAnimation:(BOOL)isNext
{
    UIViewAnimationOptions option;
    if (isNext) {
        //  UIViewAnimationOptionCurveLinear :动画匀速执行,默认值. UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果
        option = UIViewAnimationOptionCurveLinear | UIViewAnimationOptionTransitionFlipFromTop;
    }else{
        option = UIViewAnimationOptionCurveLinear | UIViewAnimationOptionTransitionFlipFromLeft;
    }
    // 转场动画
    [UIView transitionWithView:self.imageView duration:1.0 options:option animations:^{
        self.imageView.image = [self getImage:isNext];
    } completion:^(BOOL finished) {
        NSLog(@"Animation END");
    }];
}

#pragma mark 取得当前图片
- (UIImage *)getImage:(BOOL)isNext
{
    if (isNext) {
        _currentIndex = (_currentIndex +1 )%6;
    }else{
        _currentIndex = (_currentIndex -1 + 6) %6;
    }
    NSString * imageName = [NSString stringWithFormat:@"image%ld",_currentIndex];
    UIImage * image = [UIImage imageNamed:imageName];
    return image;
}
  1. 上面的转场动画演示中,其实仅仅有一个视图UIImageView做转场动画,每次转场通过切换UIImageView的内容而已。
  2. 如果有两个完全不同的视图,并且每个视图布局都很复杂,此时要在这两个视图之间进行转场可以使用+ (void)transitionFromView:(UIView )fromView toView:(UIView )toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0)方法进行两个视图间的转场。
  3. 需要注意的是默认情况下转出的视图会从父视图移除,转入后重新添加,可以通过UIViewAnimationOptionShowHideTransitionViews参数设置,设置此参数后转出的视图会隐藏(不会移除)转入后再显示。

注意:转场动画设置参数完全同基本动画参数设置;同直接使用转场动画不同的是使用UIView的装饰方法进行转场动画其动画效果较少,因为这里无法直接使用私有API。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值