iOS 利用动画和贝塞尔实现咻咻效果

先上效果图:


圆形

方形

思路分析:

这四种风格其实就是两种, 一种是动画效果在视图View的内部, 另一种是在视图的外部! 我们可以尝试封装自定义 View 设置相关属性去实现这两个风格. 点击时候触及动画, 说明要在这个 View 上添加手势! 分析动画效果其实是两种, 第一种是视图的比例由小到大,第二种是动画显示效果是渐渐变暗! 那么我们可以把两种效果写到一个动画组中!还有一个问题是效果的形状, 也就是 Layer 动画展示的形状有方形有圆形, 这个形状就需要我们思考如何去绘制和判断!

代码分析:

首先要创建自定义一个 View 类去实现点击有动画的效果! 因为分析有两种风格(在外在内)的动画, 因此要在. h 文件中声明属性去接收外界告知的风格! 我们还可以添加一些供外界修改的值, 比如动画的边界粗细, 填充颜色, 动画时间等等这里我用一个颜色举例! 外界可提供一个颜色, 怎么用具体代码中有!

typedef NS_ENUM(NSUInteger, FlashButtonType){
  # 风格定义一个枚举类型的去表示 分别是代表动画在里面和外面 (便于理解)
  DDFlashButtonInner = 0,
  DDFlashButtonOuter = 1

};
# 定义的两个属性
@property (strong, nonatomic) UIColor *flashColor;
@property (assign, nonatomic) FlashButtonType buttonType;

# 写这个方法可以对 View 的子视图上的子控件进行操作, 可以不把子控件都暴露出去
- (void)setText:(NSString *)text withTextColor:(UIColor *)textColor;

第 2 步: 在初始化方法中,我们可以给这个 view 加一些子视图比如 UILabel 去显示一些想表达的文字(这里还可以写个方法去改变 label上 text 的属性,)! 还需要给 View 添加点击手势!

- (instancetype) initWithFrame:(CGRect)frame{

  if (self = [super initWithFrame:frame]) {
# 创建手势 并添加到 View 上
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)];
     [self addGestureRecognizer:tap];
    self.textLabel = [[UILabel alloc] initWithFrame:self.bounds];
    self.textLabel.backgroundColor = [UIColor clearColor];
    [self.textLabel setTextAlignment:NSTextAlignmentCenter];
    [self addSubview:self.textLabel];
    self.backgroundColor = [UIColor cyanColor];
# 给一个默认的风格 不设置就是代表 动画在里面
    self.buttonType = DDFlashButtonInner;
  }
  return self;
}

第 3 步: 可以给子控件给一些属性 这里有 label 还写了个方法

- (void)setText:(NSString *)text withTextColor:(UIColor *)textColor
{
# 就是给 Label 赋外界传来的值 若有其他的控件可以改一些参数用此方法
  if (text)
  {
    [self.textLabel setText:text];
  }
  if (textColor)
  {
    [self.textLabel setTextColor:textColor];
  }
}

第 4 步: 根据风格的不同我们要控制动画展示的范围, 也就是加入动画在内部就不能超过 View 的范围


# 这里就是重写了ButtonType setter方法,同时判断一下风格根据风格选择是否把超过视图 View 的部分裁剪掉
- (void)setButtonType:(FlashButtonType)buttonType
{
  _buttonType = buttonType;
    if (buttonType == DDFlashButtonInner)
  {
// 内容和子视图是夹在视图的边界内 ( 只允许 view范围内有子视图和类容可以显示 )
    self.clipsToBounds = 1;
  }else
  {// 外面可以显示
    self.clipsToBounds = 0;
  }
}

第 5 步: 准备工作做好后, 一个思路就是去写点击事件, 需要什么就去创建什么! 这先去思考点击事件中需要的东西, 都满足之后再去写完善点击事件! 动画效果首先需要动画, 另外还需要能添加动画的 Layer;首先写个得到动画的方法!

- (CAAnimationGroup *)createFlashAnimationWisthScale:(CGFloat)scale
                      duration:(CGFloat)duratiton
{
# 创建按比例收缩变大的动画
// 指定要在渲染动画性能时的关键路径 也就是图形转换的方式 这里是按收缩比例 这里也可以不用.scale 因为我们初始值设置是根据CATransform3D
  CABasicAnimation *scaleAnnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
// 动画开始点
  // 这个动画效果初值 就是本身的原始的位置
  scaleAnnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
  // 等价 scaleAnnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1, 1, 1)];
// 动画结束点
  // 在 x 轴和 y 轴的变化比例
  scaleAnnimation.toValue = [NSValue valueWithCATransform3D:(CATransform3DMakeScale(scale, scale, 1))];

# 创建透明度变换的动画
 CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
  alphaAnimation.fromValue = @1;
  alphaAnimation.toValue = @0;

# 创建动画组把上面两个动画加进去
  CAAnimationGroup *animation = [CAAnimationGroup new];
  animation.animations = @[scaleAnnimation,alphaAnimation];
// 动画效果 (节奏, Timing Function的会被用于变化起点和终点之间的插值计算.形象点说是Timing Function决定了动画运行的节奏(Pacing),比如是均匀变化(相同时间变化量相同),先快后慢,先慢后快还是先慢再快再慢.)
  animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

# 返回我们想要的动画效果组
  return animation;
}

第 6 步: 得到一个CAShapeLayer 类型的图层(因为要结合贝塞尔曲线得到形状路径), 画一个形状那么就需要有位置

- (CAShapeLayer *)creatCircleShapWithPostion:(CGPoint)position
                  pathRect:(CGRect)rect
                   radius:(CGFloat)radius
{
  CAShapeLayer *circleShap = [CAShapeLayer layer];

// 从贝塞尔曲线取到形状
  circleShap.path = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:radius].CGPath;

// 虽然得到了形状, 但是并没有得到具体的 frame(bounds) 也就是实际上并没有范围 只是可以展现动画的效果 那么锚点其实就是设置的位置点
  circleShap.position = position;
  if (self.buttonType == DDFlashButtonInner)
  {
# 在这里设置 frame 就是为了满足我们想要的锚点位置让动画效果动起来, 下面也一样, 可以不设置试试效果就明白了!
   // circleShap.bounds = CGRectMake(0, 0, radius *2, radius *2);
   circleShap.frame = CGRectMake(position.x-radius, position.y-radius, radius*2, radius*2);
    // 线宽
    circleShap.lineWidth = 1;
    // 填充的颜色 不设置默认就给黄色
    circleShap.fillColor = self.flashColor ? self.flashColor.CGColor:[UIColor yellowColor].CGColor;

  }else
  {
     circleShap.frame = self.bounds;
   // 线宽
    circleShap.lineWidth = 5;
    circleShap.fillColor = [UIColor clearColor].CGColor;
  // 边缘线的颜色 不设置就默认给个紫色
  circleShap.strokeColor = self.flashColor ? self.flashColor.CGColor:[UIColor purpleColor].CGColor;

  }

  // 不透明度 要设置成透明的 不然内部风格的时候会画出来图案点点
  circleShap.opacity = 0;
  return circleShap;
}

第 7 步 : 把点击的事件完成就 OK 了

- (void)didTap:(UITapGestureRecognizer *)tapGesture
{
// 获取点击点的位置
  CGPoint tapLocation = [tapGesture locationInView:self];
// 定义一个图层 下面分情况去给予不同形状
 CAShapeLayer *circleShape = nil;
// 默认一个变化比例 1 倍
   CGFloat scale = 1.0f;
// 获取 View 的宽和高
   CGFloat width = self.bounds.size.width, height = self.bounds.size.height;
   if (self.buttonType == DDFlashButtonInner)
  {
# 这里就是在视图内部效果, 就是以点击的点为圆心 画一个小圆(这里是半径为1) 然后让它动画起来 (不断的变大并变透明) 所以放大倍数只要能到最大的变就行了 不一定非要这样写, 你开心就好!
    CGFloat biggerEdge = width > height ? width :height;
    CGFloat radius = 1
    scale = biggerEdge / radius + 0.5;
# 调用方法获得图层 锚点位置就是点击的位置
circleShape = [self creatCircleShapWithPostion:CGPointMake(tapLocation.x , tapLocation.y ) pathRect:CGRectMake(0, 0, radius * 2, radius * 2) radius:radius];
  }else
  {
# 这个是外部动画效果 设置能放大5.5倍
    scale = 5.5f;
# 锚点位置在 View 的中心 这个图层和 View 是一样的形状范围
   circleShape = [self creatCircleShapWithPostion:CGPointMake(width /2 , height / 2) pathRect:self.bounds radius:self.layer.cornerRadius];
   }
// view图层 上添加 有形状的自定义图层
  [self.layer addSublayer:circleShape];

# 给自定义图层添加动画
  [circleShape addAnimation:[self createFlashAnimationWisthScale:scale duration:1.0f] forKey:nil];
}

最后说一句: 用的时候在 viewController 中引入, 创建自定义的 View 实例对象, 改变传入的风格和颜色就可以展示效果了!

iOS基础-动画效果的总结--(CALayer — 粉骨碎身全不怕,要留清白在人间!<小拳石>动画的思维导图基础知识:iOS能够实现动画的方式:(如上图)UIView基础实现方式一UIView基础实现方式二CoreAnimation实现方式动画的效果简述:传达状态提高用户对直接操作的感知帮助用户可视化操作的结果UIVIew的基础动画:UIKit直接将动画继承到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持.执行动画的工作由UIView类自动完成,但希望在...

原文链接:http://www.jianshu.com/p/c187c7005ce1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2016-09-18

IOS实现视频动画效果的启动图

先上效果图 实现思路 主要思路就是用一个控制器来作为播放视频的载体,然后在让这个控制器作为根视图,视频播放完成之后那就该干嘛干嘛了. 话不多说了,下面就放代码好了 先新建一个控制器AnimationViewController在控制器中新建一个属性moviePlayer,记得要先引入系统库<MediaPlayer/MediaPlayer.h> @property (nonatomic, strong) MPMoviePlayerController *moviePlayer; 设置movieP

iOS UITableView展开缩放动画实例代码

Swift - UITableView展开缩放动画 效果 源码:https://github.com/YouXianMing/Swift-Animations // // HeaderViewTapAnimationController.swift // Swift-Animations // // Created by YouXianMing on 16/8/9. // Copyright © 2016年 YouXianMing. All rights reserved. // import

iOS动画之向右拉的抽屉3D效果

首先我们忽略掉3D效果,先要做的是一个右拉的抽屉效果. 总体思路: 1.创建一个ContainerViewController容器控制器,然后把左侧选择菜单的SideMenuViewController,和右侧负责显示内容的MainViewController 添加到ContainerViewController中. 2.给容器控制器ContainerViewController添加一个手势监听,通过修改偏移量完成抽屉效果. 3.设置anchorPoint,给左侧SideMenuViewCont

iOS仿支付宝芝麻信用分数仪表盘动画效果

先看看效果图: 仪表盘动画效果.jpg 1.圆环上绿点的旋转 2.分数值及提示语的变化 3.背景色的变化 直接上主要代码: 1.自定义ZLDashboardView仪表盘文件: .h 文件: /** * 根据跃动数字 * * 确定百分比 * 现在的跳动数字-->背景颜色变化 * */ #import <UIKit/UIKit.h> @interface ZLDashboardView : UIView @property (nonatomic, strong) UIImage *bgIm

iOS利用CALayer实现动画加载的效果

首先来看看效果图 实现过程如下 控制器调用就一句代码: [self showLoadingInView:self.view]; 方便控制器如此调用,就要为控制器添加一个分类 .h文件 #import <UIKit/UIKit.h> #import "GQCircleLoadView.h" @interface UIViewController (GQCircleLoad) //显示动画 - (void)showLoadingInView:(UIView*)view; //隐

iOS实现滚动字幕的动画特效

效果图 开始上代码 滚动字幕的原理是用timer定时器间隔一定的时间来驱动scrollView上的内容偏移,来实现滚动的效果,原理比较简单,关键是有些细节需要处理好,实现流畅效果的同时要考虑到性能优化 这里是.h文件的接口方法及属性,可适应大部分自定义场景 /*初始化*/ -(instancetype)initWithFrame:(CGRect)frame textArray:(NSArray *)textArray colorArray:(NSArray *)textColorArray; /

iOS 基本动画、关键帧动画、利用缓动函数实现物理动画效果

iOS基本动画/关键帧动画/利用缓动函数实现物理动画效果 先说下基本动画部分 基本动画部分比较简单, 但能实现的动画效果也很局限 使用方法大致为: #1. 创建原始UI或者画面 #2. 创建CABasicAnimation实例, 并设置keypart/duration/fromValue/toValue #3. 设置动画最终停留的位置 #4. 将配置好的动画添加到layer层中 举个例子, 比如实现一个圆形从上往下移动, 上代码: //设置原始画面 UIView *showView = [[UI

IOS 圆球沿着椭圆轨迹做动画

前言:最近公司项目有个需求,需要实现让一个view沿着椭圆轨迹做动画,效果实现后,就自己封装做了一个小demo,使用更方便.先看效果: 椭圆.gif 效果图中的白色椭圆轨迹线其实是用贝塞尔曲线画出来的,为了清晰的看出来运动的轨迹.其实项目中是不显示轨迹线的,也就是小球是悬空运动的.若不需要删除掉即可. 实现步骤: 1.首先设定关键帧动画CAKeyframeAnimation的一些属性,比如运动时间和重复次数和calculationMode模式,我们选择kCAAnimationPaced 使得动画

iOS实现知乎和途家导航栏渐变的文字动画效果

效果图如下 分析如下: 1.导航栏一开始是隐藏的,随着scrollView滚动而渐变 2.导航栏左右两边的navigationItem是一直显示的 3.导航栏参考了途家app,使用了毛玻璃效果,背景是一张图片 4.下拉放大图片效果 5.title文字动画效果 通过简单分析,系统的导航栏实现以上效果有点困难,直接自定义一个假的导航栏更容易点 分布拆解实现以上效果 一.下拉放大header图片 - (void)viewDidLoad { [super viewDidLoad]; [self.view

IOS 波纹进度(waveProgress)动画实现

LXWaveProgress A simple wave components 一个简单的波浪进度动画,高度可定制.具体效果见Demo. 使用方法 LXWaveProgressView *progressView1 = [[LXWaveProgressView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; progressView1.center=CGPointMake(CGRectGetMidX(self.view.bounds), 270

iOS渐变圆环旋转动画CAShapeLayer CAGradientLayer

iOS渐变圆环旋转动画CAShapeLayer CAGradientLayer shape.gif demo.png - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor

iOS 屏幕解锁文字动画效果

CAGradientLayer相信大家都比较熟悉,关于其如何使用,我就不在这里废话了,网上有很多介绍,想详细了解的话,可以去看看.我只简单说下如何利用CAGradientLayer制作屏幕解锁文字动画效果. 1.创建一个CAGradientLayer对象gradLayer,设置它的frame和label.bounds一样(这里要注意一下是Label的bounds不是frame); 2.这里我给gradLayer.colors一共设置了三个颜色值,首尾颜色透明度设置成0.3,中间的颜色值透明度保持

IOS swift中的动画的实例详解

IOS swift中的动画的实例详解 UIView的通用动画 let view = UIView(frame: CGRectMake(10.0, 10.0, 100.0, 40.0)) self.view.addSubview(view) view.backgroundColor = UIColor.lightGrayColor() // 位置改变 var frame = view.frame UIView.animateWithDuration(0.6, delay: 2.0, options

iOS CAReplicatorLayer实现脉冲动画效果

iOS CAReplicatorLayer 实现脉冲动画效果,供大家参考,具体内容如下 效果图 脉冲数量.速度.半径.透明度.渐变颜色.方向等都可以设置.可以用于地图标注(Annotation).按钮长按动画效果(例如录音按钮)等. 代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo 实现原理 实现方法参考:https://github.com/shu223/Pulsator 但是觉得那些代码不够简洁,所以自己写了一个

Android UI设计系列之自定义SwitchButton开关实现类似IOS中UISwitch的动画效果(2)

做IOS开发的都知道,IOS提供了一个具有动态开关效果的UISwitch组件,这个组件很好用效果相对来说也很绚丽,当我们去点击开关的时候有动画效果,但遗憾的是Android上并没有给我们提供类似的组件(听说在Android4.0的版本上提供了具有动态效果的开关组件,不过我还没有去看文档),如果我们想实现类似的效果那该怎么办了呢?看来又得去自定义了. 公司的产品最近一直在做升级,主要做的就是把界面做的更绚丽更美观给用户更好的体验(唉,顾客是上帝......),其中的设置功能中就有开关按钮,原来的开

IOS实现碎片化动画详解

碎片化效果图 遮罩视图 在UIView中有一个maskView属性,这个属性是我们今天实现动画的最重要的变量.这个属性在iOS8之后开始使用,用来表示视图的遮罩.什么是遮罩呢?我想了很久都没有找到合适的比喻来介绍这个.简单来说,一个UIView的对象,可以通过设置alpha来改变这个视图的透明度,遮罩的实现效果也是一样的.唯一的差别在于前者是通过修改0~1之间的值来改变透明效果,作为遮罩的视图对象的backgroundColor.alpha.transform等等属性都会影响到被遮盖的视图的透明

iOS实现转场动画的3种方法示例

什么是转场动画 在 NavigationController 里 push 或 pop 一个 View Controller,在 TabBarController 中切换到其他 View Controller,以 Modal 方式显示另外一个 View Controller,这些都是 View Controller Transition.在 storyboard 里,每个 View Controller 是一个 Scene,View Controller Transition 便是从一个 Sce

Android自定义view实现水波纹进度球效果

今天我们要实现的这个view没有太多交互性的view,所以就继承view. 自定义view的套路,套路很深 1.获取我们自定义属性attrs(可省略) 2.重写onMeasure方法,计算控件的宽和高 3.重写onDraw方法,绘制我们的控件 这么看来,自定义view的套路很清晰嘛. 我们看下今天的效果图,其中一个是放慢的效果(时间调的长) 我们按照套路来. 一.自定义属性 <declare-styleable name="WaveProgressView"> <at

iOS自定义转场动画的几种情况

前言 在开发中,无论我们使用 Push 还是 Present 推出新的 ViewController 时,系统为了提高用户体验都会为我们默认加上一些过渡动画.但是,系统默认的动画总是不能满足大家各种各样的需求的,所以系统也为我们提供了在不同场景下自定义过渡动画以及通过手势控制过渡进度的实现方案. 这篇文章记录了自定义转场动画中的几种情况: 模态跳转(Present) 导航控制器跳转(Push) UITabbarController 三方框架--Lottie 效果图 预备 首先,我们现在介绍几个在