版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.08.08 |
前言
quartz
是一個通用的術(shù)語褒墨,用于描述在iOS
和MAC OS X
中整個媒體層用到的多種技術(shù) 包括圖形敬肚、動畫菜循、音頻捅膘、適配添祸。Quart 2D
是一組二維繪圖和渲染API
,Core Graphic
會使用到這組API
寻仗,Quartz Core
專指Core Animation
用到的動畫相關(guān)的庫刃泌、API
和類。CoreGraphics
是UIKit
下的主要繪圖系統(tǒng)署尤,頻繁的用于繪制自定義視圖耙替。Core Graphics
是高度集成于UIView
和其他UIKit
部分的。Core Graphics
數(shù)據(jù)結(jié)構(gòu)和函數(shù)可以通過前綴CG
來識別曹体。在app中很多時候繪圖等操作我們要利用CoreGraphic
框架俗扇,它能繪制字符串、圖形箕别、漸變色等等铜幽,是一個很強大的工具滞谢。感興趣的可以看我另外幾篇。
1. CoreGraphic框架解析(一)—— 基本概覽
2. CoreGraphic框架解析(二)—— 基本使用
功能要求
實現(xiàn)波浪線的海浪效果除抛,比如中國聯(lián)通客戶端頂部剩余流量的波浪線狮杨。
功能實現(xiàn)
下面還是直接看代碼。
1. JJCoreGraphicWaveVC.m
#import "JJCoreGraphicWaveVC.h"
#import "JJCoreGraphicWaveView.h"
#import "Masonry.h"
@interface JJCoreGraphicWaveVC ()
@end
@implementation JJCoreGraphicWaveVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"CoreGraphic實現(xiàn)波浪線";
//加載波浪線視圖
JJCoreGraphicWaveView *waveView = [[JJCoreGraphicWaveView alloc] init];
[self.view addSubview:waveView];
[waveView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.width.equalTo(@300);
make.height.equalTo(@200);
}];
}
@end
2. JJCoreGraphicWaveView.m
#import "JJCoreGraphicWaveView.h"
#define kJJCoreGraphicWaveViewScreenWidth [UIScreen mainScreen].bounds.size.width
#define kJJCoreGraphicWaveViewScreenHeight [UIScreen mainScreen].bounds.size.height
@interface JJCoreGraphicWaveView ()
@property (nonatomic, strong) UIColor *waterColor;
@property (nonatomic, assign) CGFloat waterLineY;
@property (nonatomic, assign) CGFloat waveAmplitude;
@property (nonatomic, assign) CGFloat waveCycle;
@property (nonatomic, assign) BOOL isIncrease;
@property (nonatomic, strong) CADisplayLink *waveDisplayLink;
@end
@implementation JJCoreGraphicWaveView
#pragma mark - Override Base Function
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setInitConfig];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
//初始化畫布
CGContextRef context = UIGraphicsGetCurrentContext();
//推入
CGContextSaveGState(context);
//定義前波浪path
CGMutablePathRef frontPath = CGPathCreateMutable();
//定義后波浪path
CGMutablePathRef backPath = CGPathCreateMutable();
//定義前波浪反色path
CGMutablePathRef frontReversePath = CGPathCreateMutable();
//定義后波浪反色path
CGMutablePathRef backReversePath = CGPathCreateMutable();
//畫水
CGContextSetLineWidth(context, 1);
//前波浪位置初始化
float frontY = self.waterLineY;
CGPathMoveToPoint(frontPath, NULL, 0, frontY);
//前波浪反色位置初始化
float frontReverseY = self.waterLineY;
CGPathMoveToPoint(frontReversePath, NULL, 0,frontReverseY);
//后波浪位置初始化
float backY = self.waterLineY;
CGPathMoveToPoint(backPath, NULL, 0, backY);
//后波浪反色位置初始化
float backReverseY = self.waterLineY;
CGPathMoveToPoint(backReversePath, NULL, 0, backReverseY);
for(float x = 0; x <= kJJCoreGraphicWaveViewScreenWidth; x ++){
//前波浪繪制
frontY= _waveAmplitude * sin( x/180 * M_PI + 4 * self.waveCycle/M_PI ) * 5 + self.waterLineY;
CGPathAddLineToPoint(frontPath, nil, x, frontY);
//后波浪繪制
backY= _waveAmplitude * cos( x/180 * M_PI + 3 * self.waveCycle/M_PI ) * 5 + self.waterLineY;
CGPathAddLineToPoint(backPath, nil, x, backY);
if (x>=100) {
//后波浪反色繪制
backReverseY= _waveAmplitude * cos( x/180 * M_PI + 3 * self.waveCycle/M_PI ) * 5 + self.waterLineY;
CGPathAddLineToPoint(backReversePath, nil, x, backReverseY);
//前波浪反色繪制
frontReverseY= _waveAmplitude * sin( x/180 * M_PI + 4 * self.waveCycle/M_PI ) * 5 + self.waterLineY;
CGPathAddLineToPoint(frontReversePath, nil, x, frontReverseY);
}
}
//后波浪繪制
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGPathAddLineToPoint(backPath, nil, kJJCoreGraphicWaveViewScreenWidth, rect.size.height);
CGPathAddLineToPoint(backPath, nil, 0, rect.size.height);
CGPathAddLineToPoint(backPath, nil, 0, self.waterLineY);
CGPathCloseSubpath(backPath);
CGContextAddPath(context, backPath);
CGContextFillPath(context);
//推入
CGContextSaveGState(context);
//后波浪反色繪制
CGPathAddLineToPoint(backReversePath, nil, kJJCoreGraphicWaveViewScreenWidth, rect.size.height);
CGPathAddLineToPoint(backReversePath, nil, 100, rect.size.height);
CGPathAddLineToPoint(backReversePath, nil, 100, self.waterLineY);
CGContextAddPath(context, backReversePath);
CGContextClip(context);
//彈出
CGContextRestoreGState(context);
//前波浪繪制
CGContextSetFillColorWithColor(context, [_waterColor CGColor]);
CGPathAddLineToPoint(frontPath, nil, kJJCoreGraphicWaveViewScreenWidth, rect.size.height);
CGPathAddLineToPoint(frontPath, nil, 0, rect.size.height);
CGPathAddLineToPoint(frontPath, nil, 0, self.waterLineY);
CGPathCloseSubpath(frontPath);
CGContextAddPath(context, frontPath);
CGContextFillPath(context);
//推入
CGContextSaveGState(context);
//前波浪反色繪制
CGPathAddLineToPoint(frontReversePath, nil, kJJCoreGraphicWaveViewScreenWidth, rect.size.height);
CGPathAddLineToPoint(frontReversePath, nil, 100, rect.size.height);
CGPathAddLineToPoint(frontReversePath, nil, 100, self.waterLineY);
CGContextAddPath(context, frontReversePath);
CGContextClip(context);
//推入
CGContextSaveGState(context);
//釋放
CGPathRelease(backPath);
CGPathRelease(backReversePath);
CGPathRelease(frontPath);
CGPathRelease(frontReversePath);
}
#pragma mark - Object Private Function
- (void)setInitConfig
{
self.backgroundColor = [UIColor clearColor];
self.waveAmplitude = 3.0;
self.waveCycle = 1.0;
self.waterColor = [UIColor colorWithRed:90/255.0 green:200/255.0 blue:140/255.0 alpha:1.0];
self.waterLineY = 20.0;
self.waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(waveDidRun)];
[self.waveDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
#pragma mark - Action && Notification
//CADisplayLink到忽,每秒60次刷新界面
- (void)waveDidRun
{
if (self.isIncrease) {
self.waveAmplitude += 0.03;
}
else {
self.waveAmplitude -= 0.03;
}
if (self.waveAmplitude <= 1) {
self.isIncrease = YES;
}
if (self.waveAmplitude >= 1.5) {
self.isIncrease = NO;
}
//速度控制
self.waveCycle += 0.02;
//調(diào)用drawRect方法不停的繪制
[self setNeedsDisplay];
}
@end
還有幾點要說明下:
-
CADisplayLink
頻率是每秒鐘更新60次橄教,更新速度很快。 -
JJCoreGraphicWaveView
必須給布局和大小frame
喘漏,否則- (void)drawRect:(CGRect)rect
方法是不會調(diào)用的护蝶。
功能效果
下面我們就看一下功能效果。
參考文章
后記
未完翩迈,待續(xù)~~~