iOS自定义UIButton点击动画特效
程序员文章站
2023-11-30 08:08:52
借鉴相关资料,整理了一个很有意思的button动画效果,ios自定义uibutton点击动画特效
先看一下效果图:
下面贴上代码:
viewcontroller:...
借鉴相关资料,整理了一个很有意思的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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 基于iview的router常用控制方式
下一篇: Vue+Django项目部署详解