UI基础--动画(缩放动画, 渐变动画, 左右振动, 移动动画, 组合动画)(封装好)

创建一个CAAnimation的类别

CAAnimation+HCAnimation

.h

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, Axis) {
    AxisX = 0,  ///< x轴
    AxisY,      ///< y轴
    AxisZ       ///< z轴
};

typedef NS_ENUM(NSInteger, ShakeDerection) {
    ShakeDerectionAxisX = 0,    ///< 左右
    ShakeDerectionAxisY,        ///< 上下
};

@interface CAAnimation (HCAnimation)

/**
 * 在具体的UIView上实现一个缩放的动画
 *@param   view         动画的载体
 *@param   scaleValue   最终缩放值
 *@param   repeat       动画循环次数,0表示无限循环
 *@param   duration     动画运行一次的时间
 *@return  void
 */
+ (void)showScaleAnimationInView:(UIView *)view ScaleValue:(CGFloat)scaleValue Repeat:(CGFloat)repeat Duration:(CGFloat)duration;

/**
 * 在具体的UIView上实现一个移动的动画
 *@param   view         动画的载体
 *@param   Position     最终停留的位置(中心点坐标)
 *@param   repeat       动画循环次数,0表示无限循环
 *@param   duration     动画运行一次的时间
 *@return  void
 */
+ (void)showMoveAnimationInView:(UIView *)view Position:(CGPoint)position Repeat:(CGFloat)repeat Duration:(CGFloat)duration;

/**
 * 在具体的UIView上实现一个旋转的动画
 *@param   view         动画的载体
 *@param   degree       旋转的弧度
 *@param   direction    旋转的方向
 *@param   repeat       动画循环次数,0表示无限循环
 *@param   duration     动画运行一次的时间
 *@return  void
 */
+ (void)showRotateAnimationInView:(UIView *)view Degree:(CGFloat)degree Direction:(Axis)direction Repeat:(CGFloat)repeat Duration:(CGFloat)duration;

/**
 * 在具体的UIView上实现一个透明度渐变的动画
 *@param   view         动画的载体
 *@param   alpha        最终显示的透明度
 *@param   repeat       动画循环次数,0表示无限循环
 *@param   duration     动画运行一次的时间
 *@return  void
 */
+ (void)showOpacityAnimationInView:(UIView *)view Alpha:(CGFloat)alpha Repeat:(CGFloat)repeat Duration:(CGFloat)duration;

/**
 * 在具体的UIView上实现一个震动的动画
 *@param   view         动画的载体
 *@param   offset       震动的偏移量
 *@param   derection    震动方向
 *@param   repeat       动画循环次数,0表示无限循环
 *@param   duration     动画运行一次的时间
 *@return  void
 */
+ (void)showShakeAnimationInView:(UIView *)view Offset:(CGFloat)offset Direction:(ShakeDerection)derection Repeat:(CGFloat)repeat Duration:(CGFloat)duration;

/**
 *清除具体UIView上的所有动画
 *@param   view   实施清除的对象
 *@return  void
 */
+ (void)clearAnimationInView:(UIView *)view;

@end

.m

#import "CAAnimation+HCAnimation.h"

@implementation CAAnimation (HCAnimation)

+ (void)showScaleAnimationInView:(UIView *)view ScaleValue:(CGFloat)scaleValue Repeat:(CGFloat)repeat Duration:(CGFloat)duration {

    if (repeat == 0) {
        repeat = MAXFLOAT;
    }
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

    ///动画的起始状态值
    scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    ///动画结束状态值
    scaleAnimation.toValue = [NSNumber numberWithFloat:scaleValue];

    ///循环动画执行方式,原路返回式(YES 注意:一去一回才算一个动画周期) 还是 再次从头开始(NO 注意:仅仅去一次就是一个动画周期)
    scaleAnimation.autoreverses = YES;
    ///动画结束后保持的状态:开始状态(kCAFillModeRemoved/kCAFillModeBackwards)、结束状态(kCAFillModeForwards/kCAFillModeBoth)
    scaleAnimation.fillMode = kCAFillModeForwards;
    scaleAnimation.removedOnCompletion = NO;

    ///动画循环次数(MAXFLOAT 意味无穷)
    scaleAnimation.repeatCount = repeat;
    ///一个动画持续时间
    scaleAnimation.duration = duration;

    [view.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}

+ (void)showMoveAnimationInView:(UIView *)view Position:(CGPoint)position Repeat:(CGFloat)repeat Duration:(CGFloat)duration {

    if (repeat == 0) {
        repeat = MAXFLOAT;
    }
    CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    moveAnimation.fromValue = [NSValue valueWithCGPoint:view.layer.position];
    moveAnimation.toValue = [NSValue valueWithCGPoint:position];
    moveAnimation.autoreverses = YES;
    moveAnimation.fillMode = kCAFillModeForwards;
    moveAnimation.removedOnCompletion = NO;
    moveAnimation.repeatCount = repeat;
    moveAnimation.duration = duration;
    [view.layer addAnimation:moveAnimation forKey:@"moveAnimation"];
}

+ (void)showRotateAnimationInView:(UIView *)view Degree:(CGFloat)degree Direction:(Axis)direction Repeat:(CGFloat)repeat Duration:(CGFloat)duration {
    if (repeat == 0) {
        repeat = MAXFLOAT;
    }
    NSArray *axisArray = @[@"transform.rotation.x",@"transform.rotation.y",@"transform.rotation.z"];
    CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:axisArray[direction]];
    rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    rotateAnimation.toValue = [NSNumber numberWithFloat:degree];
    rotateAnimation.autoreverses = YES;
    rotateAnimation.fillMode = kCAFillModeForwards;
    rotateAnimation.removedOnCompletion = NO;
    rotateAnimation.repeatCount = repeat;
    rotateAnimation.duration = duration;
    [view.layer addAnimation:rotateAnimation forKey:@"rotateAnimation"];
}

+ (void)showOpacityAnimationInView:(UIView *)view Alpha:(CGFloat)alpha Repeat:(CGFloat)repeat Duration:(CGFloat)duration {
    if (repeat == 0) {
        repeat = MAXFLOAT;
    }
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.fromValue=[NSNumber numberWithFloat:1.0];
    animation.toValue=[NSNumber numberWithFloat:alpha];
    animation.repeatCount = repeat;
    animation.duration = duration;
    animation.removedOnCompletion=NO;
    animation.fillMode=kCAFillModeForwards;
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    animation.autoreverses=YES;

    [view.layer addAnimation:animation forKey:@"animation"];
}

+ (void)showShakeAnimationInView:(UIView *)view Offset:(CGFloat)offset Direction:(ShakeDerection)derection Repeat:(CGFloat)repeat Duration:(CGFloat)duration {
    if (repeat == 0) {
        repeat = MAXFLOAT;
    }
    NSAssert([view.layer isKindOfClass:[CALayer class]] , @"invalid target");
    CGPoint originPos = CGPointZero;
    CGSize originSize = CGSizeZero;
    if ([view.layer isKindOfClass:[CALayer class]]) {
        originPos = [(CALayer *)view.layer position];
        originSize = [(CALayer *)view.layer bounds].size;
    }
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    //改变value来实现不同方向的震动
    CGFloat offsetX = 0;
    CGFloat offsetY = 0;
    if (derection == ShakeDerectionAxisX) {
        offsetX = offset;
    }else if (derection == ShakeDerectionAxisY){
        offsetY = offset;
    }
    animation.values = @[
                  [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)],
                  [NSValue valueWithCGPoint:CGPointMake(originPos.x-offsetX, originPos.y-offsetY)],
                  [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)],
                  [NSValue valueWithCGPoint:CGPointMake(originPos.x+offsetX, originPos.y+offsetY)],
                  [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)]
                  ];
    animation.repeatCount = repeat;
    animation.duration = duration;
    animation.fillMode = kCAFillModeForwards;
    [view.layer addAnimation:animation forKey:@"animation"];
}

+ (void)clearAnimationInView:(UIView *)view {
    [view.layer removeAllAnimations];
}

@end

在需要的地方调用就可以了.

#import "ViewController.h"
#import "CAAnimation+HCAnimation.h"

#define kBtnTag             0
#define kBtnSelectedTag     1

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.btn1.tag = kBtnTag;
    self.btn2.tag = kBtnTag;
    self.btn3.tag = kBtnTag;
    self.btn4.tag = kBtnTag;
    self.btn5.tag = kBtnTag;
    self.btn6.tag = kBtnTag;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

///缩放动画
- (IBAction)btn1Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showScaleAnimationInView:btn ScaleValue:1.5 Repeat:0 Duration:0.8];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}

///渐变动画
- (IBAction)btn2Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showOpacityAnimationInView:btn Alpha:0.1 Repeat:0 Duration:0.6];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}

///左右震动动画
- (IBAction)btn3Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showShakeAnimationInView:btn Offset:10.0 Direction:ShakeDerectionAxisX Repeat:0 Duration:0.5];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}

///移动动画
- (IBAction)btn4Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showMoveAnimationInView:btn Position:CGPointMake(btn.layer.position.x*2, btn.layer.position.y) Repeat:0 Duration:0.8];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}

///组合动画
- (IBAction)btn5Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showScaleAnimationInView:btn ScaleValue:1.5 Repeat:0 Duration:1.0];
        [CAAnimation showOpacityAnimationInView:btn Alpha:0.3 Repeat:0 Duration:1.0];
        [CAAnimation showMoveAnimationInView:btn Position:self.btn1.layer.position Repeat:0 Duration:1.0];
        [CAAnimation showRotateAnimationInView:btn Degree:2*M_PI Direction:AxisZ Repeat:0 Duration:1.0];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}

///旋转动画
- (IBAction)btn6Clicked:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.tag == kBtnTag) {
        [CAAnimation showRotateAnimationInView:btn Degree:2*M_PI Direction:AxisY Repeat:0 Duration:1.0];
    }else{
        [CAAnimation clearAnimationInView:btn];
    }
    btn.tag = btn.tag == kBtnTag ? kBtnSelectedTag : kBtnTag;
}
@end

OK...

时间: 2024-12-10 00:16:58

UI基础--动画(缩放动画, 渐变动画, 左右振动, 移动动画, 组合动画)(封装好)的相关文章

iOS开发-UI基础-汤姆猫Tom(序列帧动画)

使用UIImageView和UIButton实现Tom小案例. 功能分析:点击对应按钮后,tom实现相应的动作和声音 步骤分析: 搭建UI界面:(头部,肚子,尾巴,左脚和右脚使用的是button) 监听按钮点击 根据点击的按钮实现相应的序列帧动画 tom的动作就是一张一张的图片连续显示在屏幕上,实现动画有几种方式: 1.首尾式: //动画的开始 [UIView beginAnimations:nil context:nil]; //动画的内容 //提交动画(动画结束) [UIView commi

UI基础--手写代码实现汤姆猫动画

// // ViewController.m // TomCat // // Created by xiaomoge on 14/12/10. // Copyright (c) 2014年 xiaomoge. All rights reserved. // #import "ViewController.h" @interface ViewController () { UIButton *_btnDrink;// 喝动作按钮 UIButton *_btnEat;// 吃动作按钮 UI

【Android】21.4 图片动画缩放示例

分类:C#.Android.VS2015: 创建日期:2016-03-21 一.简介 该例子演示如何动画缩放图片,实现类似"点击看大图"的效果. 二.示例 1.运行截图    2.设计步骤 (1)添加图片 在Resources/no-dpi文件夹下添加4张图片(2个缩略图,2个大图). (2)添加ch2104MyImageButton.cs using Android.Content; using Android.Widget; using System.Drawing; using

css3的基础用法,新手必看哈(还有css3和jquery动画的对比)

第一步: 定义动画,名字可以各种起,就像方法名一样 1. 定义动画,名称为fadeIn @-webkit-keyframes fadeIn { 0% { opacity: 0; /*初始状态 透明度为0*/ } 50% { opacity: 0; /*中间状态 透明度为0*/ } 100% { opacity: 1; /*结尾状态 透明度为1*/ } } 方法里面还有很多写法: 如: /* 定义css方法,名字叫消失 Hides a leaf towards the very end of th

(六十三)Activity切换动画,包括渐变、flip、某个位置进入等等

一.当项目中需要为Activity添加动画时,可以参考这个github的源码 Activity切换动画,包括渐变.flip.某个位置进入等等项目地址:https://github.com/ophilbert/ActivityTransition效果图:类似桌面左右切换的各种效果,不过桌面并非用ViewPager实现而已文档介绍:https://github.com/jfeinstein10/JazzyViewPager/blob/master/JazzyViewPager.apk?raw=tru

如何制作css3的3d动画——以骰子旋转为例,详解css3动画属性

首先先来看两个用css3实现的炫酷的3d动画效果 1 2 3 4 5 6 你没看错,这个炫酷的效果都是用css3实现的. 下面是动画实现所需要用到的几个css3属性. 1.perspective:用来实现一个3d的场景 写3D效果的第一步是要创建一个3D场景,即索要实现效果的模块.这里用到了 perspective 属性和 perspective-origin 属性. perspective:用来定义3d动画距离浏览器的距离,单位是(px). perspective-origin:效果渲染的视角

Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)

在上一篇中我们学习了属性动画的ObjectAnimator使用,不了解的可以看看 Android属性动画Property Animation系列一之ObjectAnimator.这一篇我们来学点新的东西.做项目的时候应该碰到这种问题:根据不同条件显示或者隐藏一个控件或者布局,我们能想到的第一个方法就是 调用View.setVisibility()方法.虽然实现了显示隐藏效果,但是总感觉这样的显示隐藏过程很僵硬,让人不是很舒服,那么有没有办法能让这种显示隐藏有个过渡的动画效果呢?答案是肯定的,不言

Silverlight &amp; Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)

原文:Silverlight & Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation) 说到对象的旋转,或许就会联想到对象角度的概念.对象的旋转实现实际上就是利用对象的角度改变来实现的位置变换,在<Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)>一文中有对对象的不同角度变换的实现介绍,本篇要介绍的自由旋转(Free-form rotation)将借助<Fun

Android Animation动画详解(二): 组合动画特效

前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一番,然后再过来跟着我一起学习如何把简单的动画效果组合在一起,做出比较酷炫的动画特效吧. 一. 动画的续播 如题,大家想想,如果一个页面上包含了许多动画,这些动画要求按顺序播放,即一个动画播放完成后,继续播放另一个动画,使得这些动画具有连贯性.那该如何实现呢? 有开发经验或者是逻辑思维的人肯定会想,对