麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

[iOSUI進(jìn)階-0]Quiartz2D

2019-11-14 19:42:09
字體:
供稿:網(wǎng)友
A.簡介
1. 需要掌握的
  • drawRect:方法的使用
  • 常見圖形的繪制:線條、多邊形、圓
  • 繪圖狀態(tài)的設(shè)置:文字顏色、線寬等
  • 圖形上下文狀態(tài)的保存與恢復(fù)
  • 圖形上下文棧

1.基本圖形繪制
* 線段(線寬、線段樣式)
* 矩形(空心、實(shí)心、顏色)
* 三角形、梯形等形狀
* 橢圓/圓
* 圓弧
* 文字繪制
* 圖片繪制(pattern)
* 圖形上下文棧

2.練習(xí)(畫人)
3.模仿UIImageView
4.自定義checkbox
5.圖片裁剪
6.圖片水印
7.條紋背景
8.截圖
 
 
2.概念
Quartz 2D是一個二維繪圖引擎,同時支持iOS和Mac系統(tǒng)
Quartz 2D能完成的工作
  • 繪制圖形 : 線條/三角形/矩形/圓/弧等
  • 繪制文字
  • 繪制/生成圖片(圖像)
  • 讀取/生成PDF
  • 截圖/裁剪圖片
  • 自定義UI控件
  • … …
 
Quartz 2D能做很多強(qiáng)大的事情,例如
  • 裁剪圖片
  • 涂鴉/畫板
  • 手勢解鎖
 
B.Quartz2D在iOS開發(fā)中的價值
  • 為了便于搭建美觀的UI界面,iOS提供了UIKit框架,里面有各種各樣的UI控件
  • UILabel:顯示文字
  • UIImageView:顯示圖片
  • UIButton:同時顯示圖片和文字(能點(diǎn)擊)
  • … …

利用UIKit框架提供的控件,拼拼湊湊,能搭建和現(xiàn)實(shí)一些簡單、常見的UI界面

但是,有些UI界面極其復(fù)雜、而且比較個性化,用普通的UI控件無法實(shí)現(xiàn),這時可以利用Quartz2D技術(shù)將控件內(nèi)部的結(jié)構(gòu)畫出來,自定義控件的樣子

其實(shí),iOS中大部分控件的內(nèi)容都是通過Quartz2D畫出來的

因此,Quartz2D在iOS開發(fā)中很重要的一個價值是:自定義view(自定義UI控件)
 
C.圖形上下文
圖形上下文(Graphics Context):是一個CGContextRef類型的數(shù)據(jù)

圖形上下文的作用
保存繪圖信息、繪圖狀態(tài)
決定繪制的輸出目標(biāo)(繪制到什么地方去?)
(輸出目標(biāo)可以是PDF文件、Bitmap或者顯示器的窗口上)
Image(270)
相同的一套繪圖序列,指定不同的Graphics Context,就可將相同的圖像繪制到不同的目標(biāo)上
 
D.Quartz2D提供了以下幾種類型的Graphics Context
Bitmap Graphics Context
PDF Graphics Context
Window Graphics Context
Layer Graphics Context
PRinter Graphics Context
 
Image(271)
 
E.使用
1.自定義view
如何利用Quartz2D自定義view?(自定義UI控件)

如何利用Quartz2D繪制東西到view上?
首先,得有圖形上下文,因為它能保存繪圖信息,并且決定著繪制到什么地方去
其次,那個圖形上下文必須跟view相關(guān)聯(lián),才能將內(nèi)容繪制到view上面

自定義view的步驟
新建一個類,繼承自UIView
實(shí)現(xiàn)- (void)drawRect:(CGRect)rect方法,然后在這個方法中
取得跟當(dāng)前view相關(guān)聯(lián)的圖形上下文
繪制相應(yīng)的圖形內(nèi)容
利用圖形上下文將繪制的所有內(nèi)容渲染顯示到view上面
 
2. drawRect:
為什么要實(shí)現(xiàn)drawRect:方法才能繪圖到view上?
因為在drawRect:方法中才能取得跟view相關(guān)聯(lián)的圖形上下文

drawRect:方法在什么時候被調(diào)用?
當(dāng)view第一次顯示到屏幕上時(被加到UIWindow上顯示出來)
調(diào)用view的setNeedsDisplay或者setNeedsDisplayInRect:時
 
Image(272)
 
3.Quartz2D須知
Quartz2D的API是純C語言的

Quartz2D的API來自于Core Graphics框架


數(shù)據(jù)類型和函數(shù)基本都以CG作為前綴
CGContextRef
CGPathRef
CGContextStrokePath(ctx);
……
 
4.drawRect:中取得的上下文
在drawRect:方法中取得上下文后,就可以繪制東西到view上

View內(nèi)部有個layer(圖層)屬性,drawRect:方法中取得的是一個Layer Graphics Context,因此,繪制的東西其實(shí)是繪制到view的layer上去了

View之所以能顯示東西,完全是因為它內(nèi)部的layer
 
5.Quartz2D繪圖的代碼步驟
獲得圖形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();

拼接路徑(下面代碼是搞一條線段)
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 100, 100);

繪制路徑
CGContextStrokePath(ctx); // CGContextFillPath(ctx);
 
6.常用拼接路徑函數(shù)
新建一個起點(diǎn)
void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)

添加新的線段到某個點(diǎn)
void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)

添加一個矩形
void CGContextAddRect(CGContextRef c, CGRect rect)

添加一個橢圓
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)

添加一個圓弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
  CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
 
7.常用繪制路徑函數(shù)
Mode參數(shù)決定繪制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)

繪制空心路徑
void CGContextStrokePath(CGContextRef c)

繪制實(shí)心路徑
void CGContextFillPath(CGContextRef c)

提示:一般以CGContextDraw、CGContextStroke、CGContextFill開頭的函數(shù),都是用來繪制路徑的
 
F.小練習(xí)
1.畫線段
(1)新建single view application,拖入一個view,創(chuàng)建一個class并設(shè)置
7C034679-1E00-4A8F-A576-62B4471DE619
 
(2)在自定義的view class 中實(shí)現(xiàn)drawRect:方法
 1 //重寫drawRect: 2 - (void)drawRect:(CGRect)rect { 3     // 1.獲得圖形上下文 4     CGContextRef ctx = UIGraphicsGetCurrentContext(); 5     6     // 2.拼接圖形 7     // 2.1設(shè)置一個起點(diǎn) 8     CGContextMoveToPoint(ctx, 10, 10); 9    10     // 2.2添加一條線段,是從(10,10)到(100,100)11     CGContextAddLineToPoint(ctx, 100, 100);12    13     // 2.3從上次的位置開始再添加一條線段,是從(100,100)到(150,40)14     CGContextAddLineToPoint(ctx, 150, 40);15    16     // 2.4最后畫一條直線連接會原處,形成一個三角形17 //    CGContextAddLineToPoint(ctx, 10, 10);18     CGContextClosePath(ctx); // 回到起點(diǎn)19    20     // 3.渲染顯示到view上面21     CGContextStrokePath(ctx);22 }
 
Image(273)
 
2.畫矩形
 1 - (void)drawRect:(CGRect)rect { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 2.畫四邊形 6     CGContextAddRect(ctx, CGRectMake(10, 10, 80, 100)); 7     8     // 繪制空心圖形 9 //    CGContextStrokePath(ctx);10    11     // 繪制實(shí)心圖形12     CGContextFillPath(ctx);13 }
 
Image(274)
 
3.畫圓
 1 - (void) drawRound { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 2.1畫圓 6     CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100)); 7     8     // 2.2橢圓 9     CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 150, 100));10    11     // 渲染12     CGContextStrokePath(ctx);13 }
 
Image(275)
 
 
4.畫圓弧
 1 - (void) drawArc { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 2.圓弧 6     // X軸正方向為0角度,最后一個參數(shù)1代表逆時針方向 7     CGContextAddArc(ctx, 100, 100, 50, 0, -M_PI, 1); 8     9     // 渲染10     CGContextStrokePath(ctx);11 }

 

Image(276)
 
1     // 2.圓弧2     // X軸正方向為0角度,最后一個參數(shù)1代表逆時針方向3     CGContextAddArc(ctx, 100, 100, 50, 0, -M_PI, 0);

 

Image(277)
 
 
5.畫文字
 1 - (void) drawText { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 2.畫上文字 6     /** 7      * 如果使用已經(jīng)過期的方法 CGContextShowText,由于CG畫板是以左下角為零點(diǎn),所以字會上下顛倒過來 8      */ 9     NSString *text = @"hello, 你好啊";10 //    [text drawAtPoint:CGPointZero withAttributes:nil];11    12     CGRect r = CGRectMake(50, 50, 100, 100);13     CGContextAddRect(ctx, r);14     CGContextFillPath(ctx);15    16     NSMutableDictionary *dict = [NSMutableDictionary dictionary];17     dict[NSForegroundColorAttributeName] = [UIColor redColor]; // 前景色,就是字體顏色18     dict[NSFontAttributeName] = [UIFont systemFontOfSize:20]; // 字體19     [text drawInRect:r withAttributes:dict];20    21     // 渲染22     CGContextStrokePath(ctx);23 }
 
Image(278)
 
6.畫圖片
(1)使用已經(jīng)封裝好,不用手動轉(zhuǎn)換坐標(biāo)的方法
 1 - (void) drawImg { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 取得圖片 6     UIImage *img = [UIImage imageNamed:@"M4"]; 7     8     // 畫上圖片 9 //    [img drawAtPoint:CGPointZero]; // 原圖大小,可能顯示不全10     [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默認(rèn)是拉伸11    12     // 渲染13     CGContextStrokePath(ctx);14 }
 
(2)填充方式
a.drawAtPoint 默認(rèn)是原圖
    [img drawAtPoint:CGPointZero]; // 原圖大小,可能顯示不全
Image(279)
 
b.drawInRect 是拉伸
    [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默認(rèn)是拉伸
Image(280)
 
c.drawaspetternInRect
 1 - (void) drawImg { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4    5     // 取得圖片 6     UIImage *img = [UIImage imageNamed:@"M4Mini"]; // 小圖 7   8     // 畫上圖片 9     [img drawAsPatternInRect:CGRectMake(0, 0, 200, 200)]; // 重復(fù),可以用來做花紋10   11     // 渲染12     CGContextStrokePath(ctx);13 }
 
(3)文字水印
 1 - (void) drawImg { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 取得圖片 6     UIImage *img = [UIImage imageNamed:@"M4"]; // 大圖 7 //    UIImage *img = [UIImage imageNamed:@"M4Mini"]; // 小圖 8     9     // 畫上圖片10 //    [img drawAtPoint:CGPointZero]; // 原圖大小,可能顯示不全11     [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默認(rèn)是拉伸12 //    [img drawAsPatternInRect:CGRectMake(0, 0, 200, 200)]; // 重復(fù),可以用來做花紋13    14     // 文字15     NSString *text = @"這是一個美女";16     [text drawInRect:CGRectMake(0, 0, 100, 30) withAttributes:nil];17    18     // 渲染19     CGContextStrokePath(ctx);20 }

 

Image(281)
 
G.畫一個小黃人
利用基本的圖形描繪一個簡單地小黃人頭像
使用弧線、直線、橢圓
 
H.圖形上下文棧
為了在更改上下文設(shè)置后能夠完全、方便地恢復(fù)原來的設(shè)置
 1 - (void) contextStackDemo { 2     // 1.獲得上下文 3     CGContextRef ctx = UIGraphicsGetCurrentContext(); 4     5     // 2.存儲上下文 6     CGContextSaveGState(ctx); 7     8     // 3.設(shè)置上下文 9     CGContextSetLineCap(ctx, kCGLineCapRound);10     CGContextSetLineWidth(ctx, 10);11     [[UIColor redColor] set];12    13     // 4.畫第一條直線14     CGContextMoveToPoint(ctx, 10, 10);15     CGContextAddLineToPoint(ctx, 100, 100);16    17     // 渲染18     CGContextStrokePath(ctx);19    20     // 5.恢復(fù)上下文21     CGContextRestoreGState(ctx);22    23     // 6.第二條直線24     CGContextMoveToPoint(ctx, 100, 10);25     CGContextAddLineToPoint(ctx, 10, 100);26    27     // 渲染28     CGContextStrokePath(ctx);29 }
 
Image(282)
 
 
I.矩陣操作 裁剪
1.矩陣旋轉(zhuǎn)、縮放、移動操作
 1 - (void) testCTM { 2     CGContextRef ctx = UIGraphicsGetCurrentContext(); 3     4     CGContextSaveGState(ctx); 5     6     CGContextRotateCTM(ctx, M_PI_4 * 0.3); // 旋轉(zhuǎn) 7     CGContextScaleCTM(ctx, 0.5, 0.5); // 縮放 8     CGContextTranslateCTM(ctx, 100, 0); // 移動 9    10     CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100));11     CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 60, 60));12    13     CGContextMoveToPoint(ctx, 200, 100);14     CGContextAddLineToPoint(ctx, 50, 200);15    16     CGContextStrokePath(ctx);17   18 }
 
Image(283)
 
2.裁剪
 1 - (void) testClip { 2     CGContextRef ctx = UIGraphicsGetCurrentContext(); 3     4     // 畫一個圓 5     CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 150, 150)); 6     7     // 裁剪 8     CGContextClip(ctx); 9    10     // 加上圖片11     UIImage *img = [UIImage imageNamed:@"a9ec8a13632762d0092abc3ca2ec08fa513dc619"];12     [img drawInRect:CGRectMake(0, 0, 150, 150)];13   14     CGContextStrokePath(ctx);    15 }
 
Image(284)
 
J.重繪(刷幀)
setNeedDisplay
1.通過一個滑塊控件來控制一個圓的動態(tài)大小
(1)在storyboard中描繪一個view和一個slider
Image(285)
 
(2)拖入slider的值變化事件和view到控制器,并使用自定義類為view的class
(3)在自定義UIView類中實(shí)現(xiàn)drawRect,在適當(dāng)?shù)牡胤秸{(diào)用setNeddDisplay重繪
MyView:
 1 - (void)setRadius:(CGFloat)radius { 2     _radius = radius; 3     4     // 調(diào)用重繪/刷幀方法 5     [self setNeedsDisplay]; 6 } 7  8 // 初始化控件的時候, drawRect只會調(diào)用一次 9 - (void)drawRect:(CGRect)rect {10     CGContextRef ctx = UIGraphicsGetCurrentContext();11    12     CGContextAddArc(ctx, 125, 125, self.radius, M_PI * 2, 0, 1);13     CGContextFillPath(ctx); // 實(shí)心圓14 }
 
ViewController:
 1 @interface ViewController () 2 - (IBAction)onSlideChange:(UISlider *)sender; 3 @property (weak, nonatomic) IBOutlet MyView *circleView; 4  5 @end 6  7 @implementation ViewController 8  9 - (void)viewDidLoad {10     [super viewDidLoad];11     // Do any additional setup after loading the view, typically from a nib.12 }13 14 - (void)didReceiveMemoryWarning {15     [super didReceiveMemoryWarning];16     // Dispose of any resources that can be recreated.17 }18 19 - (IBAction)onSlideChange:(UISlider *)sender {20     self.circleView.radius = sender.value * 100;21 }22 @end
 
可以用滑條控制圓的大小
Image(286)
 
2.下雪動畫
使用定時器 Timer
使用CADisplayLink
 1 - (void)awakeFromNib { 2     // 添加定時器 3 //    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; 4     5     // 刷新更快的工具 6     CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; // 創(chuàng)建 7     8     // 添加到消息循環(huán),啟動 9     [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];10 }11 12 - (void)drawRect:(CGRect)rect {13     self.snowY += 1;14     if (self.snowY >= self.frame.size.height) {15         self.snowY = -100;16     }17     UIImage *image = [UIImage imageNamed:@"M2Mini"];18     [image drawAtPoint:CGPointMake(100, self.snowY)];19 }
 
3C60EE71-2F0B-400C-B383-1215BF964FA3
 
 
 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久精品小短片 | 久久久久99999| 久久久国产视频 | 88xx成人永久免费观看 | 久久久久久久久久久久99 | 亚洲福利视 | 成人18网站 | 一级片免费在线 | 成年片在线观看 | 日韩av成人 | 97久色| 激情大乳女做爰办公室韩国 | 免费高清一级欧美片在线观看 | 国产91丝袜在线熟 | 污视频在线免费播放 | 一区二区免费网站 | 粉嫩粉嫩一区二区三区在线播放 | 欧美高清第一页 | 色婷婷久久久久久 | 国产精品久久在线观看 | 毛片视频播放 | 草草视频免费 | 福利一区二区三区视频在线观看 | 成人男女啪啪免费观看网站四虎 | 中文字幕在线永久 | 久久蜜臀一区二区三区av | 色吧综合网 | 国产日韩三区 | 中文字幕在线观看精品 | 精品国产91久久久久久久 | 欧美一级精品片在线看 | 欧美一区二区三区不卡免费观看 | 特色一级黄色片 | 国产一国产一级毛片视频在线 | 永久av在线免费观看 | 亚洲精品永久视频 | 久久精品国产99久久久古代 | 久久久青 | 毛片在哪看| 久色porn| 欧美囗交|