iOS 仿百度外卖-个人中心(头像波浪效果)
来源:互联网 发布:淘宝培训靠谱吗 编辑:程序博客网 时间:2024/05/16 15:24
今天带来的是仿百度外卖个人中心的波浪效果,先看下效果图吧
一,项目里用到了两个类:
一个是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)
-
-
-
-
-
-
-
-
- #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
-
-
-
-
-
-
-
-
- #import "WavesView.h"
-
- @interface WavesView ()
-
-
-
-
-
-
- @property (nonatomic, strong) CADisplayLink *timer;
-
-
-
-
-
-
-
-
-
-
- @property (nonatomic, strong) CAShapeLayer *realWaveLayer;
-
-
-
- @property (nonatomic, strong) CAShapeLayer *maskWaveLayer;
-
-
-
- @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;
-
-
- }
-
-
- - (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);
-
- }
-
- CGFloat centX = self.bounds.size.width / 2;
- CGFloat centY = height * sinf(0.01 * self.waveCurvature * centX + self.offset * 0.045);
-
- if (self.waveBlock) {
-
-
- 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);
-
-
- self.realWaveLayer.path = realpath;
- self.realWaveLayer.fillColor = self.realWaveColor.CGColor;
- CGPathRelease(realpath);
-
-
- CGPathAddLineToPoint(maskpath, NULL, width, height);
- CGPathAddLineToPoint(maskpath, NULL, 0, height);
- CGPathCloseSubpath(maskpath);
-
-
- 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];
-
-
- _WavesView.imageFrame = _iconImageView.frame;
-
- __weak typeof(self)weakSelf = self;
-
- _WavesView.waveBlock = ^(CGRect imageFrame){
-
- weakSelf.iconImageView.frame = imageFrame;
-
- };
-
- [_WavesView startWaveAnimation];
-
- }
到这里,波浪形动画就完成了.....大家没事可以多看看动画的实现,对于里面有些东西我也是比较模糊的状态,但是多看多谢,慢慢的你就会发现收获还是有的...
0 0