一、object-c
创建WaterWaveView,自定义UIView
WaterWaveView.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WaterWaveView : UIView
@property(nonatomic,strong) UIColor * waveColor;//水纹颜色
@property(nonatomic,strong) UIColor * maskColor;//水纹遮罩颜色
@property(nonatomic,assign) CGFloat waveSpeed;//水纹的速度
@property(nonatomic,assign) CGFloat percent; //水深占据整个view的比例
@property(nonatomic,assign) CGFloat peak; //水纹的纵向高度
//启动水波纹
-(void)startWave;
//停止水波纹
-(void)stopWave;
@end
NS_ASSUME_NONNULL_END
WaterWaveView.m
#import "WaterWaveView.h"
typedef NS_ENUM(NSInteger ,mCurveType) {
mCurveTypeSin, // 正选
mCurveTypeCos // 余弦
};
@interface WaterWaveView ()
{
CADisplayLink * _link;//定时器,刷新页面
CGFloat _offset; //波纹移动的上下偏移
CGFloat _waveHeight;//水的深度(不包含水纹)
CAShapeLayer * waterLayer;//水的波纹
CAShapeLayer * maskLayer; //水纹的遮罩层
CGFloat _width; //视图宽度
CGFloat _height;//视图高度
}
@end
@implementation WaterWaveView
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
_width = frame.size.width;
_height = frame.size.height;
[self setDefauletProperty];
}
return self;
}
- (void)layoutSubviews
{
if (!waterLayer) {
waterLayer = [CAShapeLayer layer];
[self.layer addSublayer:waterLayer];
}
if (!maskLayer) {
maskLayer = [CAShapeLayer layer];
[self.layer addSublayer:maskLayer];
}
}
//启动水波纹
-(void)startWave
{
if (!_link) {
_link = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction)];//时间间隔为刷屏时间
[_link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
}
//停止水波纹
-(void)stopWave
{
[_link removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[_link invalidate];
_link = nil;
}
#pragma mark - 定时事件
-(void)displayLinkAction
{
_offset += self.waveSpeed;
UIBezierPath * sinPath = [self pathWithCurveType:mCurveTypeSin];
waterLayer.path = sinPath.CGPath;
waterLayer.fillColor = self.waveColor.CGColor;
UIBezierPath * cosPath = [self pathWithCurveType:mCurveTypeCos];
maskLayer.path = cosPath.CGPath;
maskLayer.fillColor = self.maskColor.CGColor;
}
-(UIBezierPath *)pathWithCurveType:(mCurveType)type
{
CGFloat startY = _waveHeight + _offset;
UIBezierPath * mutablePath = [[UIBezierPath alloc] init];
[mutablePath moveToPoint:CGPointMake(0, startY)];
CGFloat y = 0;
CGFloat x = 0;
while (x < _width) {
switch (type) {
case 0:
// y=Asin(ωx+φ)+h
y = _waveHeight + self.peak * sin(x * 2 * M_PI/_width + _offset);
break;
case 1:
y = _waveHeight + self.peak * cos(x * 2 * M_PI/_width + _offset);
break;
default:
break;
}
[mutablePath addLineToPoint:CGPointMake(x, y)];
x += 0.1;
}
[mutablePath addLineToPoint:CGPointMake(_width, _height)];
[mutablePath addLineToPoint:CGPointMake(0, _height)];
[mutablePath closePath];;
return mutablePath;
}
- (void)setPercent:(CGFloat)percent
{
_percent = percent;
_waveHeight = (1 - percent) * self.bounds.size.height;
}
-(void)setDefauletProperty
{
_waveHeight = self.bounds.size.height/2;
self.peak = self.bounds.size.height/5;
self.waveSpeed = 0.1;
}
项目中使用
WaterWaveView * headView = [[WaterWaveView alloc] initWithFrame:CGRectMake(50, 300, 280, 280)];
headView.waveColor=kHexColor(@"398AE5", 1.0);
headView.maskColor=kHexColor(@"398AE5", 0.5);
headView.percent = 0.35;
headView.wavePeed = 0.05;
headView.peak = 8;
[self.view addSubview:headView];
[headView startWave];
二、swift
创建自定义Swift的UIView,名称为:SwiftWaveView.swift
代码:
import UIKit
class SwiftWaveView: UIView {
enum mCurveType : NSInteger {
case mCurveTypeSin = 0
case mCurveTypeCos = 1
}
var _link:CADisplayLink?
var _offset:CGFloat = 0
var _waveHeight:CGFloat?
var _width:CGFloat?
var _height:CGFloat?
var _waveLayer:CAShapeLayer?
var _maskLayer:CAShapeLayer?
// 波浪移动速度
public var waveSpeed: CGFloat = 0.1 //水纹的速度
public var percent:CGFloat? {//水深占据整个view的比例
didSet{
assert(percent! >= 0.0 && percent! <= 1, "水波纹完成比例不得小于0或大于1!");
_waveHeight = _height! * (1 - percent!)
}
}
public var peak:CGFloat? //水纹的纵向高度
public var waveColor:UIColor?
public var maskColor:UIColor?
override init(frame: CGRect) {
super.init(frame: frame)
_width = frame.size.width
_height = frame.self.height
setDefaultProperty()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
print("layoutSubviews");
_width = frame.size.width
_height = frame.size.height
layoutWaveLayers()
}
// MARK: 添加水波纹Layer
func layoutWaveLayers() {
print("layoutWaveLayers");
if _waveLayer == nil {
_waveLayer = CAShapeLayer()
layer.addSublayer(_waveLayer!)
}
if _maskLayer == nil {
_maskLayer = CAShapeLayer()
layer.addSublayer(_maskLayer!)
}
}
@objc func startWave() {
if _link == nil {
_link = CADisplayLink.init(target: self, selector: #selector(displayLinkAction))
_link?.add(to: RunLoop.current, forMode: RunLoop.Mode.common)
}
}
func stopWave() {
_link?.remove(from: RunLoop.current, forMode: RunLoop.Mode.common)
_link?.invalidate()
_link = nil
}
// MARK: 定时事件
@objc func displayLinkAction() {
_offset += waveSpeed
let sinPath:UIBezierPath = pathWithCurveType(curveType: mCurveType.mCurveTypeSin)
_waveLayer?.fillColor = waveColor?.cgColor
_waveLayer?.path = sinPath.cgPath
let cosPath:UIBezierPath = pathWithCurveType(curveType: mCurveType.mCurveTypeCos)
_maskLayer?.fillColor = maskColor?.cgColor
_maskLayer?.path = cosPath.cgPath
}
//MARK: 通过曲线类型获得对应的曲线路径
func pathWithCurveType(curveType:mCurveType) -> UIBezierPath {
let startY:CGFloat = _waveHeight! + _offset
let mutablePath:UIBezierPath = UIBezierPath()
mutablePath.move(to: CGPoint.init(x: 0, y: startY))
var y : CGFloat
var x = CGFloat(0)
while x <= bounds.size.width {
// y=Asin(ωx+φ)+h
switch curveType {
case .mCurveTypeSin:
y = _waveHeight! + peak! * sin(x * 2.0 * CGFloat.pi/_width! + _offset)
case .mCurveTypeCos:
y = _waveHeight! + peak! * cos(x * 2.0 * CGFloat.pi/_width! + _offset)
}
mutablePath.addLine(to: CGPoint.init(x: CGFloat(x), y: CGFloat(y)))
x += 0.1
}
mutablePath.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height))
mutablePath.addLine(to: CGPoint(x: 0, y: bounds.size.height))
mutablePath.close();
return mutablePath
}
func setDefaultProperty() {
//设置默认值
_waveHeight = self.bounds.size.height/2;
peak = self.bounds.size.height/5;
waveSpeed = 0.1;
}
}
项目中使用:
let headView = SwiftWaveView.init(frame: CGRect(x: 50, y: 120, width: 280, height: 280))
headView.waveColor = hexColor(str: "398AE5", alpha: 1.0)
headView.maskColor = hexColor(str: "398AE5", alpha: 0.5)
headView.percent = 0.35
headView.waveSpeed = 0.05
headView.peak = 8
self.view.addSubview(headView)
headView.startWave()
绘制结果
image.png
网友评论