iOS自定义UIButton点击动画特效

借鉴相关资料,整理了一个很有意思的button动画效果,iOS自定义UIButton点击动画特效

先看一下效果图:

下面贴上代码:

ViewController:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

#import "ViewController.h"
#import "HWButton.h"

#define mainW [UIScreen mainScreen].bounds.size.width
#define mainH [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  self.view.backgroundColor = [UIColor blackColor];

  //创建控件
  [self creatButton];
}

- (void)creatButton
{
  HWButton *button = [[HWButton alloc] initWithFrame:CGRectMake(mainW * 0.5 - 60, mainH - 100, 120, 72) maxLeft:100 maxRight:100 maxHeight:300];
  [button setImage:[UIImage imageNamed:@"button"] forState:UIControlStateNormal];
  button.images = @[[UIImage imageNamed:@"Circle 1"], [UIImage imageNamed:@"Circle 2"], [UIImage imageNamed:@"Circle 3"], [UIImage imageNamed:@"Hero"]];
  button.duration = 10;
  [button addTarget:self action:@selector(buttonOnClick:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:button];
}

- (void)buttonOnClick:(HWButton *)btn
{
  [btn generateBubbleInRandom];
}

@end

HWButton:

#import <UIKit/UIKit.h>

@interface HWButton : UIButton

@property (nonatomic, assign) CGFloat maxLeft;
@property (nonatomic, assign) CGFloat maxRight;
@property (nonatomic, assign) CGFloat maxHeight;
@property (nonatomic, assign) CGFloat duration;
@property (nonatomic, strong) NSArray *images;

- (instancetype)initWithFrame:(CGRect)frame maxLeft:(CGFloat)maxLeft maxRight:(CGFloat)maxRight maxHeight:(CGFloat)maxHeight;

- (void)generateBubbleWithImage:(UIImage *)image;

- (void)generateBubbleInRandom;

@end

#import "HWButton.h"

@implementation HWButton
{
  CGPoint _startPoint;
  CGFloat _maxWidth;
  NSMutableSet *_recyclePool;
  NSMutableArray *_array;
}

- (instancetype)initWithFrame:(CGRect)frame maxLeft:(CGFloat)maxLeft maxRight:(CGFloat)maxRight maxHeight:(CGFloat)maxHeight
{
  self = [super initWithFrame:frame];
  if (self) {
    _maxHeight = maxHeight;
    _maxLeft  = maxLeft;
    _maxRight = maxRight;

    [self initData];
  }
  return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
  self = [super initWithCoder:aDecoder];
  if (self) {
    [self initData];
  }
  return self;
}

- (void)initData
{
  _array = @[].mutableCopy;
  _recyclePool = [NSMutableSet set];
}

- (void)generateBubbleInRandom
{
  CALayer *layer;

  if (_recyclePool.count > 0) {
    layer = [_recyclePool anyObject];

    [_recyclePool removeObject:layer];

  }else {
    UIImage *image = self.images[arc4random() % self.images.count];

    layer = [self createLayerWithImage:image];
  }

  [self.layer addSublayer:layer];
  [self generateBubbleWithCAlayer:layer];
}

- (void)generateBubbleWithImage:(UIImage *)image
{
  CALayer *layer = [self createLayerWithImage:image];

  [self.layer addSublayer:layer];
  [self generateBubbleWithCAlayer:layer];
}

- (void)generateBubbleWithCAlayer:(CALayer *)layer
{
  _maxWidth = _maxLeft + _maxRight + self.bounds.size.width;

  _startPoint = CGPointMake(self.frame.size.width / 2, 0);

  CGPoint endPoint = CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight);
  CGPoint controlPoint1 = CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight * 0.2);
  CGPoint controlPoint2 = CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight * 0.6);

  CGMutablePathRef curvedPath = CGPathCreateMutable();
  CGPathMoveToPoint(curvedPath, NULL, _startPoint.x, _startPoint.y);
  CGPathAddCurveToPoint(curvedPath, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);

  CAKeyframeAnimation *keyFrame = [CAKeyframeAnimation animation];
  keyFrame.keyPath = @"position";
  keyFrame.path = CFAutorelease(curvedPath);
  keyFrame.duration = self.duration;
  keyFrame.calculationMode = kCAAnimationPaced;

  [layer addAnimation:keyFrame forKey:@"keyframe"];

  CABasicAnimation *scale = [CABasicAnimation animation];
  scale.keyPath = @"transform.scale";
  scale.toValue = @1;
  scale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 0.1)];
  scale.duration = 0.5;

  CABasicAnimation *alpha = [CABasicAnimation animation];
  alpha.keyPath = @"opacity";
  alpha.fromValue = @1;
  alpha.toValue = @0.1;
  alpha.duration = self.duration * 0.4;
  alpha.beginTime = self.duration - alpha.duration;

  CAAnimationGroup *group = [CAAnimationGroup animation];
  group.animations = @[keyFrame, scale, alpha];
  group.duration = self.duration;
  group.delegate = self;
  group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  group.fillMode = kCAFillModeForwards;
  group.removedOnCompletion = NO;
  [layer addAnimation:group forKey:@"group"];

  [_array addObject:layer];
}

- (CGFloat)randomFloat
{
  return (arc4random() % 100)/100.0f;
}

- (CALayer *)createLayerWithImage:(UIImage *)image
{
  CGFloat scale = [UIScreen mainScreen].scale;
  CALayer *layer = [CALayer layer];
  layer.frame  = CGRectMake(0, 0, image.size.width / scale, image.size.height / scale);
  layer.contents = (__bridge id)image.CGImage;;
  return layer;
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
  if (flag) {
    CALayer *layer = [_array firstObject];
    [layer removeAllAnimations];
    [layer removeFromSuperlayer];
    [_array removeObject:layer];
    [_recyclePool addObject:layer];
  }
}

@end

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • IOS 解决UIButton 点击卡顿/延迟的问题

    前言 一开始还以为代码写的有问题,点击事件里面有比较耗时卡主线程的代码,逐一删减代码发现并不是这么回事. 正文 和参考文章里说的情况不完全相同,UIButton 并没有放在 UIScrollView 或 UITableView 上,但是 ViewController 是支持滑动返回的. ------------------华丽的分割线,搜索猜测解题中------------------ 解决办法:也没什么好办法,换成 ImageView 加 UITapGestureRecognizer 吧,另外

  • iOS中给自定义tabBar的按钮添加点击放大缩小的动画效果

    之前想过一些通过第三方的方式实现动画,感觉有点麻烦,就自己写了一个 不足之处还望大家多多指出 // 一句话,写在UITabBarController.m脚本中,tabBar是自动执行的方法 // 点击tabbarItem自动调用 -(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { NSInteger index = [self.tabBar.items indexOfObject:item]; [self a

  • iOS点击查看大图的动画效果

    对于图片来说,除了表情包,几乎都会被点击查看大图.今天就讲解一个查看和收起大图的动画效果,先直接看效果图: 如图所示,最开始是一个小图,点击小图可以查看大图.大图会从小图的位置和大小"弹"出来,同时背景变成半透明的阴影.点击大图或者阴影后,收起大图,同样地弹回到小图去,同时去掉阴影背景,就像是一张图片在伸大缩小一样. 现在看看这是怎么实现的.在思考一个动画的实现方法时,把动画的动作进行分解然后再一个个去思考怎么实现是一个好的习惯,我们稍微分解一下,这个动画在显示大图和收起大图的时候做了

  • iOS UIButton 点击无响应的解决办法

    前言 在日常开发中我们经常和按钮打交道,但是有时候会碰到比较难处理的问题,就是按钮不响应点击事件,这时候我们需要从下面几方面排查 按钮不响应的原因 1.按钮添加到了一个没有开启用户交互的父View上,例如UIImageView,这时候开启父试图的交互 view.userInteractionEnabled = YES 设为YES就可以解决问题 2.按钮自身被遮挡,点击的时候根本就没有点击到button,而是他上面一层View,自然就不会响应 这里有个看图层的方法,下图点击那个红框的按钮就可以看到

  • iOS自定义UIButton点击动画特效

    借鉴相关资料,整理了一个很有意思的button动画效果,iOS自定义UIButton点击动画特效 先看一下效果图: 下面贴上代码: ViewController: #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end #import "ViewController.h" #import "HWButton.h" #define mainW [UIScreen m

  • iOS自定义雷达扫描扩散动画

    本文实例为大家分享了iOS实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下 自己自定义了 一个雷达扫描/扩散效果的View. 扫描View 效果如下: 扩散View 效果如下: 自定义的代码如下: 1. RadarView.h #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, RadarViewType) { RadarViewTypeScan, RadarViewTypeDiffuse }; @interface RadarView

  • IOS自定义UIButton九宫格效果

    此篇文章给大家描写如何写自定义九宫格,因为在开发中,这种需求也是常见不少.因此,主要利用UIButton阐述的: 实列不复杂,就两三个步骤完成: 一.定义宽度与高度(self.view) #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height #define JHRGB(r,g,b) [UIColor co

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

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

  • iOS如何自定义控制器转场动画push详解

    前言 最近有些空闲时间,整理了下最近做的项目,本文主要介绍了关于iOS自定义控制器转场动画push的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 效果图: iOS7 开始苹果推出了自定义转场的 API .从此,任何可以用 CoreAnimation 实现的动画,都可以出现在两个 ViewController 的切换之间.并且实现方式高度解耦,这也意味着在保证代码干净的同时想要替换其他动画方案时只需简单改一个类名就可以了,真正体会了一把高颜值代码带来的愉悦感. 其实网

  • iOS实现点赞动画特效

    本文实例为大家分享了iOS实现点赞动画特效的具体代码,供大家参考,具体内容如下 动画的基本使用 动画的实现基本上是基于对View控件和View的layer属性进行操作,对视图进行移动,尺寸变换,透明度变换,旋转等一系列操作. 关键帧动画: 动画的实现可以分为两个部分,一部分是规定动画的变化内容,比如view需要把scale从0变化到1,这个数字是相对值,即从尺寸为0变化到正常尺寸.另一个部分是规定动画的渐变时间.这样就实现了view在规定时间完成指定变化了,这个变化的过程也可以通过参数设置为非均

  • 基于jquery css3实现点击动画弹出表单源码特效

    下图给大家展示了使用jquery css实现的点击动画弹出表单源码,有上传表单.删除表单.发送评论表单,都是通过鼠标点击图标按钮动画弹出的表单源码特效. 效果图展示如下: 在线预览    源码下载 html代码: <div class="buttonCollection"> <div class="qutton" id="qutton_upload"> <div class="qutton_dialog&q

  • Android自定义viewGroup实现点击动画效果

    本文实例为大家分享了viewGroup实现点击动画效果展示的具体代码,供大家参考,具体内容如下 public class MyCustomView extends ViewGroup implements View.OnClickListener { private OnMenuItemClickListener mMenuItemClickListener; /** * 点击子菜单项的回调接口 */ public interface OnMenuItemClickListener { void

随机推荐