iOS自定义UIButton点击动画特效
短信预约 -IT技能 免费直播动态提醒
借鉴相关资料,整理了一个很有意思的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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341