iOS 仿百度外卖-个人中心(头像波浪效果)
来源:互联网 发布:屏幕录制软件 编辑:程序博客网 时间:2024/05/17 01:32
今天带来的是仿百度外卖个人中心的波浪效果,先看下效果图吧
下载地址在这
一,项目里用到了两个类:
一个是CADisplayLink类,我用它取代了NSTimer,首先,它是利用刷帧和屏幕频率一样来重绘渲染页面,也就是说每次屏幕刷新的时候就会调用它的响应方法(屏幕一般一秒刷新60次)在绘图中需要重绘时常用它来代替NSTimer,其次,因为NSTimer调度优先级比较低,并不会准时调用,做动画的话会有卡顿的感觉
另一个是CAShapeLayer类,它属于CALayer的子类,通常结合CGPath来绘制不规则矩形图形.
其优点:
1.渲染效率高渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。
2.高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。
3.不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。
4.不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
二,下面是功能的实现(直接使用就可以)
先自定义类,基于 UIView(WavesView)
//// WavesView.h// 仿百度外卖-个人中心(头像波浪效果)//// Created by Amydom on 16/12/28.// Copyright © 2016年 Amydom. All rights reserved.//#import <UIKit/UIKit.h>typedef void(^WavesBlock)(CGRect myFrame);@interface WavesView : UIView/** * 浪弯曲度 */@property (nonatomic, assign) CGFloat waveCurvature;/** * 浪速 */@property (nonatomic, assign) CGFloat waveSpeed;/** * 浪高 */@property (nonatomic, assign) CGFloat waveHeight;/** * 实浪颜色 */@property (nonatomic, strong) UIColor *realWaveColor;/** * 遮罩浪颜色 */@property (nonatomic, strong) UIColor *maskWaveColor;@property (nonatomic, copy) WavesBlock waveBlock;@property (nonatomic , assign)CGRect imageFrame;- (void)stopWaveAnimation;- (void)startWaveAnimation;@end
//// WavesView.m// 仿百度外卖-个人中心(头像波浪效果)//// Created by Amydom on 16/12/28.// Copyright © 2016年 Amydom. All rights reserved.//#import "WavesView.h"@interface WavesView ()/** * 定时器 CADisplayLink:利用刷帧和屏幕频率一样来重绘渲染页面,也就是说每次屏幕刷新的时候就会调用它的响应方法(屏幕一般一秒刷新60次),在绘图中需要重绘时常用它来代替NSTimer,因为NSTimer调度优先级比较低,并不会准时调用,做动画的话会有卡顿的感觉 */@property (nonatomic, strong) CADisplayLink *timer;/** * 实浪动画 CAShapeLayer:CALayer的子类,通常结合CGPath来绘制不规则矩形图形 其优点: 1.渲染效率高渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。 2.高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。 3.不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。 4.不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。 */@property (nonatomic, strong) CAShapeLayer *realWaveLayer;/** * 遮罩浪动画 */@property (nonatomic, strong) CAShapeLayer *maskWaveLayer;/** * <#Description#> */@property (nonatomic, assign) CGFloat offset;@end@implementation WavesView#pragma mark - 初始化- (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self setUp]; } return self;}-(void)setUp{ //初始化 self.waveSpeed = 0.5; self.waveCurvature = 1.5; self.waveHeight = 4; self.realWaveColor = [UIColor whiteColor]; self.maskWaveColor = [[UIColor whiteColor] colorWithAlphaComponent:0.4]; [self.layer addSublayer:self.realWaveLayer]; [self.layer addSublayer:self.maskWaveLayer]; }#pragma mark - lazyload- (CAShapeLayer *)realWaveLayer{ if (!_realWaveLayer) { _realWaveLayer = [CAShapeLayer layer]; CGRect frame = self.bounds; frame.origin.y = frame.size.height-self.waveHeight; frame.size.height = self.waveHeight; _realWaveLayer.frame = frame; _realWaveLayer.fillColor = self.realWaveColor.CGColor; } return _realWaveLayer; }- (CAShapeLayer *)maskWaveLayer{ if (!_maskWaveLayer) { _maskWaveLayer = [CAShapeLayer layer]; CGRect frame = self.bounds; frame.origin.y = frame.size.height-self.waveHeight; frame.size.height = self.waveHeight; _maskWaveLayer.frame = frame; _maskWaveLayer.fillColor = self.maskWaveColor.CGColor; } return _maskWaveLayer; }- (void)setWaveHeight:(CGFloat)waveHeight{ _waveHeight = waveHeight; CGRect frame = self.bounds; frame.origin.y = frame.size.height - self.waveHeight; frame.size.height = self.waveHeight; _realWaveLayer.frame = _maskWaveLayer.frame = frame; }#pragma mark - 动画- (void)startWaveAnimation{ self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)]; [self.timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; }- (void)stopWaveAnimation{ [self.timer invalidate]; self.timer = nil; }//描述路径,并用CAShapeLayer绘制出来- (void)wave{ self.offset += self.waveSpeed; //获取宽,高 CGFloat width = CGRectGetWidth(self.frame); CGFloat height = self.waveHeight; //真实波浪 CGMutablePathRef realpath = CGPathCreateMutable(); CGPathMoveToPoint(realpath, NULL, 0, height); CGFloat realY = 0.f; //遮罩波浪 CGMutablePathRef maskpath = CGPathCreateMutable(); CGPathMoveToPoint(maskpath, NULL, 0, height); CGFloat maskY = 0.f; for (CGFloat x = 0.f; x <= width; x++) { realY = height * sinf(0.01 * self.waveCurvature * x + self.offset * 0.045); CGPathAddLineToPoint(realpath, NULL, x, realY); maskY = -realY; CGPathAddLineToPoint(maskpath, NULL, x, maskY); } //变化的中间 Y 值 CGFloat centX = self.bounds.size.width / 2; CGFloat centY = height * sinf(0.01 * self.waveCurvature * centX + self.offset * 0.045); if (self.waveBlock) { //修改头像view的高度 CGRect iconFrame = self.imageFrame; iconFrame.origin.y = CGRectGetHeight(self.frame)-CGRectGetHeight(self.imageFrame) + centY - self.waveHeight; self.imageFrame = iconFrame; self.waveBlock(self.imageFrame); } //真实波浪 CGPathAddLineToPoint(realpath, NULL, width, height); CGPathAddLineToPoint(realpath, NULL, 0, height); CGPathCloseSubpath(realpath); //描述路径后利用CAShapeLayer类绘制不规则图形 self.realWaveLayer.path = realpath; self.realWaveLayer.fillColor = self.realWaveColor.CGColor; CGPathRelease(realpath); //遮罩波浪 CGPathAddLineToPoint(maskpath, NULL, width, height); CGPathAddLineToPoint(maskpath, NULL, 0, height); CGPathCloseSubpath(maskpath); //描述路径后利用CAShapeLayer类绘制不规则图形 self.maskWaveLayer.path = maskpath; self.maskWaveLayer.fillColor = self.maskWaveColor.CGColor; CGPathRelease(maskpath); }@end
然后是调用,这里就简单的说明下如何调用(在 viewController 里)
首先创建的头像的 image(我是通过懒加载创建的)
- (UIImageView *)iconImageView{ if (!_iconImageView) { _iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.WavesView.frame.size.width/2 - 30, 0, 60, 60)]; _iconImageView.layer.borderColor = [UIColor whiteColor].CGColor; _iconImageView.layer.borderWidth = 2; _iconImageView.layer.cornerRadius = 30; } return _iconImageView;}
然后创建 wavesView,并且把创建好的 image的 frame 传过去
- (void)viewDidLoad { [super viewDidLoad]; //创建对线 self.WavesView = [[WavesView alloc]initWithFrame:CGRectMake(0, 22, self.view.frame.size.width, 150)]; self.WavesView.backgroundColor =[UIColor redColor]; [self.view addSubview:self.WavesView]; [_WavesView addSubview:self.iconImageView]; //这里把头像的 frame 传入到 wavesView里,让其通过 frame来计算该变量 _WavesView.imageFrame = _iconImageView.frame; //防止循环引用 __weak typeof(self)weakSelf = self; _WavesView.waveBlock = ^(CGRect imageFrame){ //修改头像view的frame(时时的通过 block 回调改变的 frame) weakSelf.iconImageView.frame = imageFrame; }; //开始执行 [_WavesView startWaveAnimation]; }
到这里,波浪形动画就完成了.....大家没事可以多看看动画的实现,对于里面有些东西我也是比较模糊的状态,但是多看多谢,慢慢的你就会发现收获还是有的...
0 0
- iOS 仿百度外卖-个人中心(头像波浪效果)
- iOS 仿百度外卖-个人中心(头像波浪效果)
- CSS3高仿百度外卖头像波浪效果
- iOS开发封装篇-模仿百度外卖波浪头像效果
- 仿百度外卖个人界面动画效果
- 百度外卖-- 波浪效果实现
- 零耦合仿百度外卖波浪动画
- Android波浪动态图(仿百度外卖、淘宝app用户界面用到的动画效果)
- iOS 仿 UC 浏览器个人中心 (下拉实现果冻效果)
- iOS 仿 UC 浏览器个人中心 (下拉实现果冻效果)
- iOS 仿百度外卖,饿了么-点餐效果(加入购物车效果)
- iOS 仿百度外卖-首页重力感应
- CoordinateLayout 自定义Behavior 仿百度外卖效果 实践
- Android 仿iOS头像选择效果
- iOS 仿百度外卖,饿了么-商品列表页
- 个人中心,设置头像
- 开源开源. 高仿百度外卖
- iOS UI篇15- 个人中心设置头像
- ORACLE强制停止存储过程
- ZCMU-1654
- android library存放路径
- @的三种作用
- 92. Reverse Linked List II
- iOS 仿百度外卖-个人中心(头像波浪效果)
- kvc总结
- Ubuntu 16.04 apt-get搭建LAMP环境
- 安卓方法——onBackPressed()
- Maven 项目管理
- 报表删除时报错“请先删除发布的报表”
- crontab格式问题
- Matlab调用Java类入门
- 查询数据库中是否存在某张表