
版权声明:本文为博主原创文章,未经博主允许不得转载。
第一:先看效果图形
第二:本绘图要了解的知识
1、 间隔性的定时器知识
dispatch_source_t timer 是GCD 的一个创建一个间隔性的定时器的形式。具体写法:
/* 定时器对象的创建 。其中:@<#dispatchQueue#> 改参数是设置Cup 处理的优先级( 可以是主线程)*/
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, <#dispatchQueue#>);
/* 这是定时器的设置*/
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, <#intervalInSeconds#> *NSEC_PER_SEC, <#leewayInSeconds#> * NSEC_PER_SEC);
/* 每次间隔都要会回调的方法*/
dispatch_source_set_event_handler(timer, ^{
<#code to be executed when timer fires#>
});
/* 定时器的开始*/
dispatch_resume(timer);
定时器的清楚:
/* 清楚时间*/
dispatch_source_cancel(self.timer);
double NextPointValue = sin(CFAbsoluteTimeGetCurrent()) + ((double)rand()/(double)RAND_MAX);
/* 转换对象,使其存入容器*/
NSNumber * NextPointObject = [NSNumber numberWithDouble:NextPointValue];
static inline CGAffineTransform
CGAffineTransformMakeScaleTranslate(CGFloat sx ,CGFloat sy,CGFloat dx ,CGFloat dy){
return CGAffineTransformMake(sx, 0.f, 0.f, sy, dx, dy);
}
CGMutablePathRef Paths = CGPathCreateMutable(); 路径的创建,同时要注意无论是在ARC 自动管理内存的情况 下,也要注意路径的释放:
/* 释放路径*/
CGPathRelease(Paths);
//
// ElectrocardiogramView.m
// 滚动图形(心电图)
//
// Created by MAC on 16/10/10.
// Copyright © 2016年 NetworkCode小贱. All rights reserved.
//
#import "ElectrocardiogramView.h"
@interface ElectrocardiogramView()
/* 获取存放数据点的数组*/
@property(nonatomic,readwrite,strong) NSMutableArray * PointsArray;
/* 创建一个内置定时器(系统)*/
@property(nonatomic,readwrite,strong) dispatch_source_ttimer;
@end
/* 每个点的间隔*/
const CGFloat KXScale = 5.0;
/* 每个图像的高度*/
const CGFloat KYScale = 100.0;
/* 创建一个中心对称的函数*/
static inline CGAffineTransform
CGAffineTransformMakeScaleTranslate(CGFloat sx ,CGFloatsy,CGFloat dx ,CGFloat dy){
return CGAffineTransformMake(sx, 0.f, 0.f, sy, dx, dy);
}
@implementation ElectrocardiogramView
-(instancetype)initWithFrame:(CGRect)frame{
if (self == [super initWithFrame:frame]) {
/* 设置视图的背景色。注意:在代码的情况下一定要加。xib 的情况下可以不加*/
self.backgroundColor = [UIColor whiteColor];
/* 设置定时器*/
[self CreateUI];
}
return self;
}
-(void)awakeFromNib{
[super awakeFromNib];
[self CreateUI];
}
#pragma mark -- 设置时间
-(void)CreateUI{
/* 初始化点数的数组容器*/
self.PointsArray = [NSMutableArray array];
/* 创建一个弱引用对象*/
__weak id weekSelf = self;
/* 时间间隔*/
double delayInSeconds = 0.25;
/* 创建时间对象 */
self.timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,dispatch_get_main_queue());
dispatch_source_set_timer(self.timer,dispatch_walltime(NULL, 0),(unsigned)(delayInSeconds *NSEC_PER_SEC), 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
/* 更新数据点*/
[weekSelf updatePoints];
});
dispatch_resume(self.timer);
}
#pragma mark 获取新的点数
-(void)updatePoints{
/* 获取随机产生的点数*/
double NextPointValue =sin(CFAbsoluteTimeGetCurrent()) + ((double)rand()/(double)RAND_MAX);
/* 转换对象,使其存入容器*/
NSNumber * NextPointObject = [NSNumbernumberWithDouble:NextPointValue];
/* 将其存入数组内*/
[self.PointsArray addObject:NextPointObject];
/* 计算画布能够绘制的个数*/
NSInteger CanvasCount = (NSInteger)floorl(self.frame.size.width/KXScale);
/* 从数组中清楚超出画布的点数*/
if ([self.PointsArray count] > CanvasCount) {
[self.PointsArrayremoveObjectsInRange:NSMakeRange(0,self.PointsArray.count- CanvasCount)];
}
/* 进行绘制*/
[self setNeedsDisplay];
}
#pragma mark -- 进行绘制的代码
- (void)drawRect:(CGRect)rect {
/* 判断数组里面是否有数据,否自不进行绘制*/
if ([self.PointsArray count]==0) {
return;
}
/* 或取上下文*/
CGContextRef ContextRef = UIGraphicsGetCurrentContext();
/* 设置路径的颜色*/
CGContextSetStrokeColorWithColor(ContextRef, [UIColormagentaColor].CGColor);
/* 设置画笔的宽度*/
CGContextSetLineWidth(ContextRef, 5);
/* 设置画之间的接口样式*/
CGContextSetLineJoin(ContextRef, kCGLineJoinRound);
/* 创建一个可变的路径 ( 注意:后面要对其释放)*/
CGMutablePathRef Paths = CGPathCreateMutable();
/* 获取画布的高度一半*/
CGFloat CanvasMidHeightFloat = self.bounds.size.height* 0.5;
/* 创建一个旋转对象。注意:这是实现图像的平移*/
CGAffineTransform transform =CGAffineTransformMakeScaleTranslate(KXScale, KYScale, 0, CanvasMidHeightFloat);
/* 设置画笔的起始点( 注意:数据记得转化)*/
CGFloat startY = [self.PointsArray[0] floatValue];
/* 设置起始画笔*/
CGPathMoveToPoint(Paths, &transform, 0, startY);
/* 批量将点数*/
for (NSUInteger x =1; x<self.PointsArray.count; ++x) {
/* 进行数据转化*/
startY = [self.PointsArray[x] floatValue];
/* 将其添加到路径里面*/
CGPathAddLineToPoint(Paths, &transform, x, startY);
}
/* 进行绘制*/
CGContextAddPath(ContextRef, Paths);
/* 释放路径*/
CGPathRelease(Paths);
/* 闭合路径*/
CGContextStrokePath(ContextRef);
}
- (void)dealloc {
/* 清楚时间*/
dispatch_source_cancel(self.timer);
}
@end