Now the live software is really fire, because the need to write a button with animated bubbles, some of the animation in the code has reference to other children's shoes, here is extremely grateful!
. h file
@interface Yybubblebutton:uibutton@property (nonatomic, assign) CGFloat maxleft;//floats to the left maximum distance @property (nonatomic, Assign) CGFloat maxright;//floats to the right maximum distance @property (nonatomic, assign) cgfloat maxheight;//floats the highest distance @property (nonatomic, Assign) CGFloat duration;//a set of pictures played out @property (nonatomic, copy) Nsarray *images;//picture array//init-(instancetype) initWithFrame: (cgrect) frame folatmaxleft: (cgfloat) Maxleft folatmaxright: (cgfloat) Maxright Folatmaxheight: (cgfloat) maxheight;//start Animation-(void) startbubble; @end
. m file
@interface Yybubblebutton () @property (Nonatomic,strong) Nstimer *timer; @property (nonatomic,assign) cgfloat maxWidth; @property (nonatomic,assign) cgpoint startPoint; @property (nonatomic,strong) Nsmutablearray *layerarray;@ End@implementation yybubblebutton//Initialization-(instancetype) initWithFrame: (CGRect) frame folatmaxleft: (CGFloat) MaxLeft Folatmaxright: (cgfloat) maxright folatmaxheight: (cgfloat) maxheight{self = [super Initwithframe:frame]; if (self) {_maxleft = Maxleft; _maxright = Maxright; _maxheight = MaxHeight; _layerarray = [Nsmutablearray array]; } return self;} External method Start bubble-(void) startbubble{Self.timer = [Nstimer scheduledtimerwithtimeinterval:self.duration/self.images.count Target:self selector: @selector (generatebubble) Userinfo:nil Repeats:yes]; [[Nsrunloop Currentrunloop]addtimer:self.timer formode:uitrackingrunloopmode];} -(void) generatebubble{Calayer *layer =[calayer layer];; UIImage *image = self.images[arc4random ()% Self.images.counT]; layer = [self createlayerwithimage:image]; [Self.layer Addsublayer:layer]; [Self generatebubblebylayer:layer];} Create a layer-(Calayer *) with an image 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) Generatebubblebylayer: (calayer*) layer{_maxwidth = _maxleft + _maxright; _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); Uibezierpath *path = [Uibezierpath Bezierpathwithcgpath:curvedpath]; [Path Addcurvetopoint:endpoint controlpoint1:_startpoint controlpoint2:controlpoint1]; Cakeyframeanimation *keyframe = [cakeyframeanimation animation]; Keyframe.keypath = @ "position"; Keyframe.path = path. Cgpath; 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"]; [Self.layerarray Addobject:layer];} -(void) dealloc{[Self.layerarray removeallobjects];} -(void) Animationdidstop: (Caanimation *) Anim finished: (BOOL) flag{if (flag) {Calayer *layer = [Self.layerarra Y Firstobject]; [Layer removeallanimations]; [Layer Removefromsuperlayer]; [Self.layerarray Removeobject:layer]; }}-(CGFloat) randomfloat{return (Arc4random ()%)/100.0f;}
The invocation method is simple:
@interface Viewcontroller ()
@property (Nonatomic,strong) Yybubblebutton *button;
@end
@implementation Viewcontroller
-(void) Viewdidload {
[Super Viewdidload];
Self.button = [[Yybubblebutton alloc]initwithframe:cgrectmake] folatmaxleft:50 folatmaxright:50 FOLATMAXHEIGHT:150];
Self.button.backgroundColor = [Uicolor Redcolor];
[Self.button settitle:@ "point Me" forstate:uicontrolstatenormal];
Self.button.images = @[[uiimage imagenamed:@ "heart3"],[uiimage imagenamed:@ "heart4"],[uiimage imagenamed:@ "Heart5"] , [UIImage imagenamed:@ "heart6"];
Self.button.duration = 4.0;
[Self.view AddSubview:self.button];
[Self.button startbubble];
}
Note: If you load a large number of pictures, it is not recommended to load with the Imagenamed method
iOS faux live UIButton with bubble animations