CATextLayer与 CAShapeLayer(波浪)
效果
XYWaterWaveView.h文件
#import <UIKit/UIKit.h>
@interface XYWaterWaveView : UIView
/**
* 波纹振幅 默认30
*/
@property (nonatomic ,assign) CGFloat waveAmplitude;
/**
* 振幅周期 默认200
*/
@property (nonatomic ,assign) CGFloat waveCycle;
/**
* 波纹速度 默认 0.2
*/
@property (nonatomic ,assign) CGFloat waveSpeed;
/**
* 波纹高度 默认为300
*/
@property (nonatomic ,assign) CGFloat waterWaveHeight;
/**
* 波纹颜色 默认红色
*/
@property (nonatomic, strong) UIColor* waveColor;
/**
* 开始
*/
- (void)startWave;
@end
XYWaterWaveView.m文件
#import "XYWaterWaveView.h"
@interface XYWaterWaveView()
{
CGFloat _height;
CGFloat _width;
}
/**
* 波纹偏移
*/
@property (nonatomic ,assign) CGFloat offsetX;
/**
* 波纹频率
*/
@property (nonatomic ,assign) CGFloat waveRate;
/**
* 定时器
*/
@property (nonatomic, strong) CADisplayLink *waveDisplaylink;
/**
* 波纹图层
*/
@property (nonatomic, strong) CAShapeLayer *waveLayer;
/**
* 背景图层
*/
@property (nonatomic, strong) CAShapeLayer *backLayer;
/**
* 介绍
*/
@property (nonatomic, strong) CATextLayer *textLayer;
@end
@implementation XYWaterWaveView
#pragma mark -- init
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initData];
}
return self;
}
- (void)initData{
/**
Asin(rt + x)
A:waveAmplitude
r:waveRate
x:offsetX
*/
//振幅
self.waveAmplitude = 30.0f;
//周期
self.waveCycle = 200.0f;
//频率
self.waveRate = 2*M_PI/self.waveCycle;
//偏移
self.offsetX = 0.0f;
//高度
self.waterWaveHeight = 300.0f;
//速度
self.waveSpeed = 0.2f;
//颜色
self.waveColor = [UIColor redColor];
_height = self.frame.size.height;
_width = self.frame.size.width;
}
#pragma mark - set
- (void)setWaveAmplitude:(CGFloat)waveAmplitude{
_waveAmplitude = waveAmplitude;
}
- (void)setWaveCycle:(CGFloat)waveCycle{
_waveCycle = waveCycle;
_waveRate = 2*M_PI/_waveCycle;
}
- (void)setWaterWaveHeight:(CGFloat)waterWaveHeight{
_waterWaveHeight = waterWaveHeight;
NSString *text = [NSString stringWithFormat:@"%.2f%@",_waterWaveHeight/_height*100,@"%"];
_textLayer.string = text;
}
- (void)setWaveSpeed:(CGFloat)waveSpeed{
_waveSpeed = waveSpeed;
}
#pragma mark -- 开始
- (void)startWave{
if (_waveDisplaylink) {
return;
}
if (self.waveLayer == nil) {
// 创建第一个波浪Layer
_waveLayer = [CAShapeLayer layer];
_waveLayer.fillColor = self.waveColor.CGColor;
[self.layer addSublayer:_waveLayer];
}
if (self.backLayer == nil) {
_backLayer = [CAShapeLayer layer];
_backLayer.frame = self.bounds;
_backLayer.fillColor = [UIColor yellowColor].CGColor;
_backLayer.backgroundColor = [UIColor blackColor].CGColor;
[self.layer addSublayer:_backLayer];
}
if (self.textLayer == nil) {
_textLayer = [CATextLayer layer];
_textLayer.foregroundColor = [UIColor blackColor].CGColor;
_textLayer.alignmentMode =kCAAlignmentJustified;
_textLayer.wrapped =YES;
_textLayer.frame = CGRectMake((_width - 150)/2, (_height - 40)/2, 150, 40);
UIFont *font = [UIFont systemFontOfSize:40];
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef =CGFontCreateWithFontName(fontName);
_textLayer.font = fontRef;
_textLayer.fontSize = font.pointSize;
CGFontRelease(fontRef);
NSString *text = [NSString stringWithFormat:@"%.2f%@",_waterWaveHeight/_height*100,@"%"];
_textLayer.string = text;
_textLayer.contentsScale = [UIScreen mainScreen].scale;
[self.layer addSublayer:_textLayer];
[_backLayer setMask:_textLayer];
}
// 启动定时调用
_waveDisplaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave:)];
[_waveDisplaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)getCurrentWave:(CADisplayLink *)dicplayLink{
// 波浪位移
self.offsetX += self.waveSpeed;
if (self.waterWaveHeight > _height - self.waveAmplitude) {
self.waterWaveHeight = _height - self.waveAmplitude;
}
[self setCurrentWaveLayerPath];
}
- (void)setCurrentWaveLayerPath{
CGMutablePathRef path = CGPathCreateMutable();
CGFloat currentWavePointY = _height - self.waterWaveHeight;
CGPathMoveToPoint(path, nil, 0, currentWavePointY);
for (float x = 0.0f; x <= _width ; x++) {
// 正弦波浪公式
CGFloat y = self.waveAmplitude * sin(self.waveRate * x + self.offsetX) + currentWavePointY;
CGPathAddLineToPoint(path, nil, x, y);
}
CGPathAddLineToPoint(path, nil, _width, _height);
CGPathAddLineToPoint(path, nil, 0, _height);
CGPathCloseSubpath(path);
self.waveLayer.path = path;
CGMutablePathRef backPath = CGPathCreateMutableCopy(path);
self.backLayer.path = backPath;
CGPathRelease(backPath);
CGPathRelease(path);
}
#pragma mark -- 停止
- (void)reset
{
[self stopWave];
[_waveLayer removeFromSuperlayer];
_waveLayer = nil;
}
- (void)stopWave{
[_waveDisplaylink invalidate];
_waveDisplaylink = nil;
}
- (void)dealloc{
[self reset];
}
@end
ViewController调用
-(void)viewDidLoad {
[super viewDidLoad];
waterWaveView = [[XYWaterWaveView alloc]initWithFrame:self.view.bounds];
waterWaveView.backgroundColor = [UIColor clearColor];
[self.view addSubview:waterWaveView];
[waterWaveView startWave];
//振幅
UILabel* label1 = [[UILabel alloc]initWithFrame:CGRectMake(0, 20, 60, 40)];
label1.text = @"振幅";
[self.view addSubview:label1];
UISlider* slider1 = [[UISlider alloc]initWithFrame:CGRectMake(40, 20, 280, 40)];
slider1.minimumValue = http://blog.csdn.net/xiaoxiaobukuang/article/details/20.0;
slider1.maximumValue = 40.0;
slider1.value = 30;
[slider1 addTarget:self action:@selector(slider1:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider1];
//周期
UILabel* label2 = [[UILabel alloc]initWithFrame:CGRectMake(0, 80, 60, 40)];
label2.text = @"周期";
[self.view addSubview:label2];
UISlider* slider2 = [[UISlider alloc]initWithFrame:CGRectMake(40, 80, 280, 40)];
slider2.minimumValue = http://blog.csdn.net/xiaoxiaobukuang/article/details/100.0;
slider2.maximumValue = 300.0;
slider2.value = 200;
[slider2 addTarget:self action:@selector(slider2:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider2];
//速度
UILabel* label3 = [[UILabel alloc]initWithFrame:CGRectMake(0, 140, 60, 40)];
label3.text = @"速度";
[self.view addSubview:label3];
UISlider* slider3 = [[UISlider alloc]initWithFrame:CGRectMake(40, 140, 280, 40)];
slider3.minimumValue = http://blog.csdn.net/xiaoxiaobukuang/article/details/0.1f;
slider3.maximumValue = 0.3f;
slider3.value = 0.2f;
[slider3 addTarget:self action:@selector(slider3:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider3];
//高度
UILabel* label4 = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 60, 40)];
label4.text = @"高度";
[self.view addSubview:label4];
UISlider* slider4 = [[UISlider alloc]initWithFrame:CGRectMake(40, 200, 280, 40)];
slider4.minimumValue = http://blog.csdn.net/xiaoxiaobukuang/article/details/0;
slider4.maximumValue = self.view.frame.size.height;
slider4.value = 300;
[slider4 addTarget:self action:@selector(slider4:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider4];
}
- (void)slider1:(UISlider *)slider{
waterWaveView.waveAmplitude = slider.value;
}
- (void)slider2:(UISlider *)slider{
waterWaveView.waveCycle = slider.value;
}
- (void)slider3:(UISlider *)slider{
waterWaveView.waveSpeed = slider.value;
}
- (void)slider4:(UISlider *)slider{
waterWaveView.waterWaveHeight = slider.value;
}