宽容他人,放过自己。

UIView动画

Posted on By anchoriteFili

1. 弹性动画


UIVIew弹性动画.zip

#pragma mark 点击事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    UITouch *touch = touches.anyObject;
    CGPoint location = [touch locationInView:self.view];
    
    /**
     创建弹性动画
     damping:阻尼,范围0-1,阻尼月接近于0,弹性效果越明显
     velocity: 弹性复位的速度
     */
    
    [UIView animateWithDuration:5.0 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
        _imageView.center = location;
    } completion:nil];
}

补充–动画设置参数

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

1.常规动画属性设置(可以同时选择多个进行设置)
名称 说明
UIViewAnimationOptionLayoutSubviews 动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction 动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState 所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat 重复运行动画。
UIViewAnimationOptionAutoreverse 动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration 忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedCurve 忽略嵌套动画速度设置。
UIViewAnimationOptionAllowAnimatedContent 动画过程中重绘视图(注意仅仅适用于转场动画)。
UIViewAnimationOptionShowHideTransitionViews 视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)
UIViewAnimationOptionOverrideInheritedOptions 不继承父动画设置或动画类型。
2.动画速度控制(可从其中选择一个设置)
名称 说明
UIViewAnimationOptionCurveEaseInOut 动画先缓慢,然后逐渐加速。
UIViewAnimationOptionCurveEaseIn 动画逐渐变慢。
UIViewAnimationOptionCurveEaseOut 动画逐渐加速。
UIViewAnimationOptionCurveLinear 动画匀速执行,默认值。
3.转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置)
名称 说明  
UIViewAnimationOptionTransitionNone 没有转场动画效果。  
UIViewAnimationOptionTransitionFlipFromLeft 从左侧翻转效果。  
UIViewAnimationOptionTransitionFlipFromRight 从右侧翻转效果。  
UIViewAnimationOptionTransitionCurlUp 向后翻页的动画过渡效果。  
UIViewAnimationOptionTransitionCurlDown 向前翻页的动画过渡效果。  
UIViewAnimationOptionTransitionCrossDissolve 旧视图溶解消失显示下一个新视图的效果。  
UIViewAnimationOptionTransitionFlipFromTop 从上方翻转效果。 UIViewAnimationOptionTransitionFlipFromBottom 从底部翻转效果。

2. 关键帧动画


UIView关键帧动画.zip

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
//    UITouch *touch = touches.anyObject;
//    CGPoint location = [touch locationInView:self.view];
    
    /**
     关键帧动画
     options:
     delay:延期
     */
    
    [UIView animateKeyframesWithDuration:0.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
        
        //第二个关键帧(准确的说第一个关键帧是开始位置):从0秒开始持续50%的时间,也就是5.0*0.5=2.5秒
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
            _imageView.center = CGPointMake(80.0, 220.0);
        }];
        
        //第三个关键帧,从0.5*5.0秒开始,持续5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{
            _imageView.center = CGPointMake(45.0, 300);
        }];
        
        //第四个关键帧:从0.75*5.0秒开始,持所需5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
            _imageView.center = CGPointMake(55.0, 400.0);
        }];
        
    } completion:^(BOOL finished) {
        NSLog(@"动画结束");
    }];
}

补充–动画设置参数

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

1.常规动画属性设置(可以同时选择多个进行设置)
名称 说明
UIViewAnimationOptionLayoutSubviews 动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction 动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState 所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat 重复运行动画。
UIViewAnimationOptionAutoreverse 动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration 忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedOptions 不继承父动画设置或动画类型。
2.动画模式设置(同前面关键帧动画动画模式一一对应,可以从其中选择一个进行设置)
名称 说明
UIViewKeyframeAnimationOptionCalculationModeLinear 连续运算模式。
UIViewKeyframeAnimationOptionCalculationModeDiscrete 离散运算模式。
UIViewKeyframeAnimationOptionCalculationModePaced 均匀执行运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubic 平滑运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubicPaced 平滑均匀运算模式。

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

3. UIView转场动画


UIVIew转场动画.zip

#import "ViewController.h"

#define IMAGE_COUNT 5

@interface ViewController () {
    UIImageView *_imageVeiw;
    int _currentIndex;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //定义图片控件
    _imageVeiw = [[UIImageView alloc] init];
    _imageVeiw.frame = CGRectMake(0, 60, self.view.frame.size.width, self.view.frame.size.height-120);
    
    _imageVeiw.contentMode = UIViewContentModeScaleAspectFit;
    _imageVeiw.image = [UIImage imageNamed:@"0"];
    [self.view addSubview:_imageVeiw];
    
    //添加手势
    UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(leftSwipe:)];
    leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:leftSwipeGesture];
    
    UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(rightSwipe:)];
    rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:rightSwipeGesture];
    
}

#pragma mark 向左划
- (void)leftSwipe:(UISwipeGestureRecognizer *)gesture {
    [self transitionAnimation:YES];
}

#pragma mark 向右划
- (void)rightSwipe:(UISwipeGestureRecognizer *)gesture {
    [self transitionAnimation:NO];
}

#pragma mark 转场动画
- (void)transitionAnimation:(BOOL)isNext {
    
    UIViewAnimationOptions option;
    if (isNext) {
        option = UIViewAnimationOptionCurveLinear|UIViewAnimationOptionTransitionFlipFromBottom;
    } else {
        option = UIViewAnimationOptionCurveLinear|UIViewAnimationOptionTransitionFlipFromLeft;
    }
    
    [UIView transitionWithView:_imageVeiw duration:1.0 options:option animations:^{
        _imageVeiw.image = [self getImage:isNext];
    } completion:nil];
    
}

#pragma mark 取得当前图片
- (UIImage *)getImage:(BOOL)isNext {
    
    if (isNext) {
        _currentIndex = (_currentIndex + 1)%IMAGE_COUNT;
    } else {
        _currentIndex = (_currentIndex - 1 + IMAGE_COUNT)%IMAGE_COUNT;
    }
    
    NSString *imageName = [NSString stringWithFormat:@"%d",_currentIndex];
    
    return [UIImage imageNamed:imageName];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

上面的转场动画演示中,其实仅仅有一个视图UIImageView做转场动画,每次转场通过切换UIImageView的内容而已。如果有两个完全不同的视图,并且每个视图布局都很复杂,此时要在这两个视图之间进行转场可以使用

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

方法进行两个视图间的转场,需要注意的是默认情况下转出的视图会从父视图移除,转入后重新添加,可以通过UIViewAnimationOptionShowHideTransitionViews参数设置,设置此参数后转出的视图会隐藏(不会移除)转入后再显示。

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