欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS自定义UIButton点击动画特效

程序员文章站 2023-11-30 08:08:52
借鉴相关资料,整理了一个很有意思的button动画效果,ios自定义uibutton点击动画特效 先看一下效果图: 下面贴上代码: viewcontroller:...

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

先看一下效果图:

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

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