OCiOS开发:绘图与曲线
来源:互联网 发布:九浅一深网络剧百度云 编辑:程序博客网 时间:2024/06/08 05:56
简介
iOS上,所有的绘制,无论是否采用OpenGL、Quartz、UIKit、或者 Core Animation—都发生在UIView对象的区域内,即子类化
UIView
,在drawRect
方法中进行绘制。视图定义绘制发生的屏幕区域。如果使用系统提供的视图,绘制工作会自动得到处理。然而,如果定义自己的定制视图,则必须自行提供绘制代码。
Core Graphics 绘图
常用绘图函数
// 1、绘制椭圆CGContextAddEllipseInRect(CGContextRef context, CGRect rect)// 2、绘制虚线CGContextSetLineDash(CGContextRef c, CGFloat phase, const CGFloat lengths[], size_t count)// 3、绘制圆弧CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat radius)CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)// 4、绘制曲线CGContextAddCurveToPoint(CGContextRef c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y)// 5、绘制直线 CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)// 6、绘制曲线CGContextAddRect(CGContextRef __nullable c, CGRect rect)
填充
1、为图形填充颜色的几个函数:
// 1、填充矩形CGContextFillRect(context, rectangl);// 2、填充椭圆或圆CGContextFillEllipseInRect(context, rectangle);// 3、填充路径CGContextFillPath(context);
注意:在填充颜色之前首先要调用
CGContextSetFillColorWithColor()
定制填充颜色。
2、代码示例:
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 创建一个椭圆,如果 width = height 则是一个圆 CGRect rectangle = CGRectMake(100, 100, 200, 200); CGContextAddEllipseInRect(context, rectangle); CGContextStrokePath(context); // 填充 // 1、设置填充颜色 CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); // 2、填充椭圆 CGContextFillEllipseInRect(context, rectangle);}
绘制直线
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 确定第一个点 CGContextMoveToPoint(context, 100, 100); // 确定第二个点 CGContextAddLineToPoint(context, 200, 300); // 开始绘图 CGContextStrokePath(context); }
绘制椭圆
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 创建一个椭圆,如果 width = height 则是一个圆 CGRect rectangle = CGRectMake(100, 100, 200, 200); CGContextAddEllipseInRect(context, rectangle); CGContextStrokePath(context);}
绘制三角形
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 创建三个点 CGPoint point1 = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds) - 80); CGPoint point2 = CGPointMake(CGRectGetMidX(self.bounds) - 80, CGRectGetMidY(self.bounds) + 100); CGPoint point3 = CGPointMake(CGRectGetMidX(self.bounds) + 80, CGRectGetMidY(self.bounds) + 100); // 连接三个点 // 1、设置起点 CGContextMoveToPoint(context, point1.x, point1.y); // 2、设置连接点 CGContextAddLineToPoint(context, point2.x, point2.y); CGContextAddLineToPoint(context, point3.x, point3.y); CGContextAddLineToPoint(context, point1.x, point1.y); // 绘图 CGContextStrokePath(context);}
绘制虚线
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // lengths 指明虚线如何交替绘制 // lengths {10, 10}表示先绘制10个点,再跳过10个点,再绘制10个点,如此反复绘制; // lengths {5, 10, 5}表示先绘制5个点,再跳过10个点,再绘制5个点,再跳过5个点,如此反复绘制; CGFloat lengths[] = {10, 10}; // 第1个参数:上下文 // 第2个参数:phase值,如果设值为5,则在绘制第一段的时候执行(n - 5)个点,n为虚线交替绘制方式第1个元素值。 // 第3个参数:虚线交替绘制方式 // 第4个参数:虚线交替绘制方式集合元素个数 CGContextSetLineDash(context, 0, lengths, 2); // 设置虚线起点 CGContextMoveToPoint(context, 100, 100); // 设置虚线终点 CGContextAddLineToPoint(context, 300, 300); // 开始绘制 CGContextStrokePath(context);}
绘制弧线
方法1:
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 设置圆心 CGPoint centerPoint = {200, 300}; // 设置半径 CGFloat radius = 100; // 设置起始角度 CGFloat startAngle = 0; // 设置结束角度 CGFloat endAngle = M_PI; // 设置绘制方向:1为顺时针, 0为逆时针 int clockwise = 1; // 绘制弧线 // 第1个参数:上下文 // 第2个参数:圆心.x // 第3个参数:圆心.y // 第4个参数:半径 // 第5个参数:起始角度 // 第6个参数:结束角度 // 第7个参数:旋转方向 CGContextAddArc(context, centerPoint.x, centerPoint.y, radius, startAngle, endAngle, clockwise); CGContextStrokePath(context);}
方法2:
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 通过指定2个切点,还有角度,调用CGContextAddArcToPoint()绘制。 // 圆弧起点 CGPoint firstPoint = {100 ,300}; CGPoint middlePoint = {200 ,200}; CGPoint endPoint = {300 ,300}; CGContextMoveToPoint(context, firstPoint.x, firstPoint.y); CGContextAddArcToPoint(context, middlePoint.x, middlePoint.y, endPoint.x, endPoint.y, 130); CGContextStrokePath(context);}
绘制曲线
- (void)drawRect:(CGRect)rect { // 获取上下文(画布) CGContextRef context = UIGraphicsGetCurrentContext(); // 设置线条宽度 CGContextSetLineWidth(context, 3.0); // 设置线条颜色 CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 创建四个点 CGPoint firstPoint = {20, 200}; CGContextMoveToPoint(context, firstPoint.x, firstPoint.y); // 顶峰点 CGPoint topPoint = {90, 40}; // 低峰点 CGPoint bottomPoint = {230, 360}; // 末尾点 CGPoint endPoint = {300, 200}; // 贝兹曲线是通过一个起始点,然后通过两个控制点,还有一个终止点,调用CGContextAddCurveToPoint()函数绘制。 CGContextAddCurveToPoint(context, topPoint.x, topPoint.y, bottomPoint.x, bottomPoint.y, endPoint.x, endPoint.y); CGContextStrokePath(context);}
注意:如果需要绘制多个峰值,可继续绘制曲线,只需将二次绘制曲线起点置为上一次曲线终点即可。
UIBezierPath 绘图
绘制多边形
- (void)drawRect:(CGRect)rect { // 设置画笔颜色 [[UIColor redColor] setStroke]; UIBezierPath * path = [[UIBezierPath alloc]init]; // 设置起点 [path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds))]; // 添加点 [path addLineToPoint:CGPointMake(100, 100)]; [path addLineToPoint:CGPointMake(120, 80)]; [path addLineToPoint:CGPointMake(150, 100)]; // 封闭路径 [path closePath]; // 设直线条宽度 [path setLineWidth:2]; // 设置拐角处的效果为圆角 [path setLineJoinStyle:kCGLineJoinRound]; // 设置结束处的效果为圆角 [path setLineCapStyle:kCGLineCapRound]; // 开始绘制 [path stroke]; // 填充 // 1、设置填充颜色 [[UIColor brownColor] setFill]; // 2、开始填充 [path fill];}
绘制弧形
- (void)drawRect:(CGRect)rect { // 设置填充颜色 [[UIColor redColor] setFill]; UIBezierPath * path = [[UIBezierPath alloc]init]; // 设置圆心 [path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds))]; // 画弧 CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); [path addArcWithCenter:center // 圆心 radius:80 // 半径 startAngle:0 // 起始角度 endAngle:M_PI_2 // 结束角度 clockwise:YES]; // 是否顺时针 // 封闭路径 [path closePath]; // 填充 [path fill];}
注意:以上绘图直接在
drawRect
方法里面执行,如果不在此方法中执行,需要通过CAShapeLayer
类渲染。
拓展
CAShapeLayer实现动画绘制
效果展示
代码示例
- (void)viewDidLoad { [super viewDidLoad]; CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init]; shapeLayer.frame = CGRectMake(0, 0, 150, 150); // 使用position来确定layer的位置 shapeLayer.position = self.view.center; // clockwise控制顺时针或逆时针 // 绘制路径,画圆 shapeLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(shapeLayer.bounds), CGRectGetMidY(shapeLayer.bounds)) radius:CGRectGetMidX(shapeLayer.bounds) startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath; // 设置图层的路径渲染颜色 shapeLayer.strokeColor = [UIColor blueColor].CGColor; // 设置图层的填充颜色 shapeLayer.fillColor = [UIColor clearColor].CGColor; // 设置路径宽度 shapeLayer.lineWidth = 2; [self.view.layer addSublayer:shapeLayer]; // 使用高级动画中的基本动画,做渲染的关键字为strokeEnd CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; // 设置持续时间 basicAnimation.duration = 3; // 设置起始帧 basicAnimation.fromValue = @0; // 设置结束帧 basicAnimation.toValue = @1; // 设置重复次数 basicAnimation.repeatCount = HUGE_VAL; // 设置是否反向执行 basicAnimation.autoreverses = NO; // 用一个字符串标识这个动画,内容是任意的。 [shapeLayer addAnimation:basicAnimation forKey:@"strokeEnd"];}
触摸绘图
效果展示
代码示例
#import "DrawingView.h"enum { undoTag = 100, clearTag};@interface DrawingView () { NSMutableArray *_lines; /**< 存储绘制的线 */}@end@implementation DrawingView- (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor whiteColor]; // 初始化集合 _lines = [NSMutableArray array]; // 撤销 UIButton *undoButton = [UIButton buttonWithType:UIButtonTypeSystem]; undoButton.bounds = CGRectMake(0, 0, 50, 40); undoButton.center = CGPointMake(self.bounds.size.width - 50, 55); [self setButtonAttributeWithButton:undoButton title:@"撤销" tag:undoTag]; [self addSubview:undoButton]; // 清空 UIButton *clearButton = [UIButton buttonWithType:UIButtonTypeSystem]; clearButton.bounds = CGRectMake(0, 0, 50, 40); clearButton.center = CGPointMake(40, 55); [self setButtonAttributeWithButton:clearButton title:@"清空" tag:clearTag]; [self addSubview:clearButton]; } return self;}- (void)drawRect:(CGRect)rect { // 异常处理 if (_lines.count == 0) { return; } // 解决点点击之后再绘制奔溃的问题 [_lines removeObject:@[]]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, 3.0); CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); // 步骤:取出一条线 -》 取得线上的每一个点 -》绘图 for (int i = 0; i < _lines.count; i++) { NSMutableArray *points = _lines[i]; for (int j = 0; j < points.count - 1; j++) { CGPoint currentPoint = [points[j] CGPointValue]; CGPoint nextPoint = [points[j + 1] CGPointValue]; // 连接两点 CGContextMoveToPoint(context, currentPoint.x, currentPoint.y); CGContextAddLineToPoint(context, nextPoint.x, nextPoint.y); } } // 开始绘制 CGContextStrokePath(context);}#pragma mark - Touches methods- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSMutableArray *newPoints = [NSMutableArray array]; [_lines addObject:newPoints];}- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:self]; NSValue *value = [NSValue valueWithCGPoint:point]; [_lines.lastObject addObject:value]; // 调用此方法会直接调用drawRect方法 [self setNeedsDisplay];}#pragma mark - Private methods- (void)setButtonAttributeWithButton:(UIButton *)button title:(NSString *)title tag:(NSInteger)tag { button.tag = tag; button.layer.borderWidth = 0.5; button.layer.borderColor = [UIColor blackColor].CGColor; button.layer.cornerRadius = 6; [button setTitle:title forState:UIControlStateNormal]; [button addTarget:self action:@selector(respondsToButton:) forControlEvents:UIControlEventTouchUpInside];}#pragma mark - responds events- (void)respondsToButton:(UIButton *)sender { switch (sender.tag) { case undoTag: { [_lines removeLastObject]; [self setNeedsDisplay]; } break; case clearTag: { [_lines removeAllObjects]; [self setNeedsDisplay]; } default: break; }}@end
注意:
DrawingView
为UIView
的子类;
0 0
- OCiOS开发:绘图与曲线
- OCiOS开发:录音与音效
- OCiOS开发:地图与定位
- OCiOS开发:媒体播放器 AVPlayer 与 AVPlayerViewController
- OCiOS开发:Masonry的安装与使用
- OCiOS开发:多线程与消息通知
- OCiOS开发:延迟调用
- OCiOS开发:界面传值
- OCiOS开发:NSURLConnection 网络请求
- OCiOS开发:集合视图 UICollectionView
- OCiOS开发:汉字转拼音
- OCiOS开发:CAGradientLayer 渐变色
- OCiOS开发:NSURLSession 网络请求
- OCiOS开发:音频播放器 AVAudioPlayer
- OCiOS开发:使用相册、照相机和录像
- OCiOS开发:手动创建CoreData数据模型
- Quartz2D绘图闭合曲线
- 绘图(直线和曲线)
- 国内一些热门的在线教育网站
- Git 命令及工具
- cocos2d中的屏幕坐标系和OPenGL坐标系转换
- ASP网页中的Base64加密、解密函数代码
- 为什么样本方差(sample variance)的分母是 n-1?
- OCiOS开发:绘图与曲线
- Unique Paths
- IOS_UI_传值
- 挑战自我
- iOS开发-webView添加头部与尾部控件
- 1001. 害死人不偿命的(3n+1)猜想 (15)
- 安装ionic
- 数据结构基础 算法实现
- 我学习编程的一个错误