当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS自定义UIButton点击动画特效

iOS自定义UIButton点击动画特效

2019年07月23日  | 移动技术网移动技术  | 我要评论

借鉴相关资料,整理了一个很有意思的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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网