iOS仿直播带有气泡动画的UIButton

现在直播软件确实很火,因为需要就写了一个带有动画气泡的按钮,代码中的部分动画有参考到其他童鞋,在这里万分感谢!
.h文件
@interface YYBubbleButton : UIButton @property (nonatomic, assign)CGFloat maxLeft;//漂浮左边最大距离
@property (nonatomic, assign)CGFloat maxRight;//漂浮右边最大距离
@property (nonatomic, assign)CGFloat maxHeight;//漂浮最高距离
@property (nonatomic, assign)CGFloat duration;//一组图片播放完的时间
@property (nonatomic, copy)NSArray *images;//图片数组 //init
-(instancetype)initWithFrame:(CGRect)frame
folatMaxLeft:(CGFloat)maxLeft
folatMaxRight:(CGFloat)maxRight
folatMaxHeight:(CGFloat)maxHeight; //开始动画
-(void)startBubble; @end
.m文件
@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 //初始化
-(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;
}
//外部方法 开始气泡
-(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];
} //创建带有Image的Layer
- (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)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.layerArray firstObject];
[layer removeAllAnimations];
[layer removeFromSuperlayer];
[self.layerArray removeObject:layer];
} }
- (CGFloat)randomFloat{
return (arc4random() % 100)/100.0f;
}
调用方法很简单:
@interface ViewController ()
@property(nonatomic,strong)YYBubbleButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.button = [[YYBubbleButton alloc]initWithFrame:CGRectMake(150, 300, 50, 20) folatMaxLeft:50 folatMaxRight:50 folatMaxHeight:150];
self.button.backgroundColor = [UIColor redColor];
[self.button setTitle:@"点我" 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];
}
注意:如果加载大量图片,不建议用imageNamed方法加载
iOS仿直播带有气泡动画的UIButton的更多相关文章
- iOS仿支付宝首页的刷新布局效果
代码地址如下:http://www.demodashi.com/demo/12753.html XYAlipayRefreshDemo 运行效果 动画效果分析 1.UI需要变动,向上滑动的时候,顶部部 ...
- iOS开发UI篇—核心动画(转场动画和组动画)
转自:http://www.cnblogs.com/wendingding/p/3801454.html iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的 ...
- iOS开发UI篇—核心动画(关键帧动画)
转自:http://www.cnblogs.com/wendingding/p/3801330.html iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimatio ...
- 最近这么火的iOS视频直播
快速集成iOS基于RTMP的视频推流 http://www.jianshu.com/p/8ea016b2720e iOS视频直播初窥:高仿<喵播APP> http://www.jiansh ...
- iOS CAEmitterLayer 实现粒子发射动画效果
iOS CAEmitterLayer 实现粒子发射动画效果 效果图 代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo 动 ...
- iOS仿支付宝首页效果
代码地址如下:http://www.demodashi.com/demo/12776.html 首先看一下效果 状态栏红色是因为使用手机录屏的原因. 1.问题分析 1.导航栏A有两组控件,随着tabl ...
- iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码
iOS精选源码 扩展内容的cell - folding-cell 一个近乎完整的可识别中国身份证信息的Demo 可自动快速... JPImageresizerView 仿微信的图片裁剪 带年月和至今以 ...
- jquery仿搜狐投票动画代码
体验效果:http://hovertree.com/texiao/jquery/21/ 这是一款基于jquery实现的仿搜狐投票动画特效源码,运行该源码可见VS图标首先出现在中间位置,紧接着随着投票比 ...
- iOS开发UI篇—核心动画(UIView封装动画)
iOS开发UI篇—核心动画(UIView封装动画) 一.UIView动画(首尾) 1.简单说明 UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画 ...
随机推荐
- iOS TextField用法大全
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...
- response 下载文件
String basePath = "D://test.json"; String filename = basePath.substring(basePath.lastIndex ...
- 基础算法之选择排序Selection Sort
原理 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾.以此类推,直到所有元素均排序完毕.一种简单直观的排序算 ...
- Sql Server如何新建计划任务
打开Sql Server数据库,在管理中找到维护计划功能,右击维护计划选择维护计划向导.如图所示: 打开维护计划向导后,在第一个步骤下输入计划名称. 输入完计划名称后,点击右下角的更改按钮,这里是配置 ...
- 在引用KindEditor编辑器时,运行时出现以下错误:错误46 找不到类型或命名空间名称“LitJson”(是否缺少 using 指令或程序集引用?)
将asp.net下bin文件夹下的文件LitJSON.dll拷贝到工程的bin目录下,并在工程中添加引用 在后台加入: using LitJson;
- 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)
1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...
- shell算数运算
((i=$j+$k)) 等价于 i=`expr $j + $k`((i=$j-$k)) 等价于 i=`expr $j -$k`((i=$j*$k)) 等价于 i=`exp ...
- [转]用CSS给SVG <use>的内容添加样式
来源:http://www.w3cplus.com/svg/styling-svg-use-content-css.html?utm_source=tuicool&utm_medium=ref ...
- 如何用fir.im 命令行工具 打包上传
1.注册fir.拿到token 2.安装 fir-cli 使用 Ruby 构建, 无需编译, 只要安装相应 gem 即可. $ ruby -v # > 1.9.3 $ gem install f ...
- 利用flash精确定位asp.net的图像热点区域
Asp.net的热点区域控件非常有用,但是对于热点区域如何精确定位,设定矩形,圆和多边形要素点的位置,用flash能够精确定位,在flash中制作热点区域的部分,可以是矩形,图形或者文字,然后对于这部 ...