繪圖路徑
a.簡單說明
在畫線的時候,方法的內部默認創建一個path。它把路徑都放到了path里面去。
1.創建路徑 cgmutablepathref 調用該方法相當于創建了一個路徑,這個路徑用來保存繪圖信息。
2.把繪圖信息添加到路徑里邊。
以前的方法是點的位置添加到ctx(圖形上下文信息)中,ctx 默認會在內部創建一個path用來保存繪圖信息。
在圖形上下文中有一塊存儲空間專門用來存儲繪圖信息,其實這塊空間就是cgmutablepathref。
3.把路徑添加到上下文中。
代碼示例:
繪制一條直線的代碼:
//1.獲取圖形上下文
cgcontextref ctx=uigraphicsgetcurrentcontext();
//2.繪圖(畫線)
//設置起點
cgcontextmovetopoint(ctx, 20, 20);
//設置終點
cgcontextaddlinetopoint(ctx, 200, 300);
//渲染
cgcontextstrokepath(ctx);
上面的代碼和下面的代碼是等價的。
//1.獲取圖形上下文
cgcontextref ctx=uigraphicsgetcurrentcontext();
//2.繪圖
//2.1創建一條直線繪圖的路徑
//注意:但凡通過quartz2d中帶有creat/copy/retain方法創建出來的值都必須要釋放
cgmutablepathref path=cgpathcreatemutable();
//2.2把繪圖信息添加到路徑里
cgpathmovetopoint(path, null, 20, 20);
cgpathaddlinetopoint(path, null, 200, 300);
//2.3把路徑添加到上下文中
//把繪制直線的繪圖信息保存到圖形上下文中
cgcontextaddpath(ctx, path);
//3.渲染
cgcontextstrokepath(ctx);
//4.釋放前面創建的兩條路徑
//第一種方法
cgpathrelease(path);
//第二種方法
// cfrelease(path);
}
b.直接使用path的好處:
第一種代碼的閱讀性不好,不便于區分。使用path,則一個path就代表一條路徑。
比如:如果要在上下文中繪制多個圖形,這種情況下建議使用path。
代碼示例:
- (void)drawrect:(cgrect)rect
{
//1.獲取圖形上下文
cgcontextref ctx=uigraphicsgetcurrentcontext();
//2.繪圖
//2.a 畫一條直線
//2.a.1創建一條繪圖的路徑
//注意:但凡通過quartz2d中帶有creat/copy/retain方法創建出來的值都必須要釋放
cgmutablepathref path=cgpathcreatemutable();
//2.a.2把繪圖信息添加到路徑里
cgpathmovetopoint(path, null, 20, 20);
cgpathaddlinetopoint(path, null, 200, 300);
//2.a.3把路徑添加到上下文中
//把繪制直線的繪圖信息保存到圖形上下文中
cgcontextaddpath(ctx, path);
//2.b畫一個圓
//2.b.1創建一條畫圓的繪圖路徑(注意這里是可變的,不是cgpathref)
cgmutablepathref path1=cgpathcreatemutable();
//2.b.2把圓的繪圖信息添加到路徑里
cgpathaddellipseinrect(path1, null, cgrectmake(50, 50, 100, 100));
//2.b.3把圓的路徑添加到圖形上下文中
cgcontextaddpath(ctx, path1);
//3.渲染
cgcontextstrokepath(ctx);
//4.釋放前面創建的兩條路徑
//第一種方法
cgpathrelease(path);
cgpathrelease(path1);
//第二種方法
// cfrelease(path);
}
效果:
提示:如果是畫線,那么就創建一條路徑(path)用來保存畫線的繪圖信息,如果又要重新畫一個圓,那么就可以創建一條新的路徑來專門保存畫圓的繪圖信息。
注意:
但凡通過quarzt2d中帶有creat/copy/retain方法創建出來的值都必須手動的釋放
有兩種方法可以釋放前面創建的路徑:
(1)cgpathrelease(path);
(2)cfrelease(path);
說明:cfrelease屬于更底層的cocafoundation框架
ps:補充知識點:
畫四邊形的一些方法:
第一種方式:通過連接固定的點繪制四邊形
第二種方式:指定起點和寬高繪制四邊形
第三種方式:把第二種方式中的兩步合并成一步。
第四種方式(oc的方法):繪制實心的四邊形,注意沒有空心的方法
第五種:畫根線,設置線條的寬度(通過這種方式可以畫斜的四邊形)
代碼示例:
//
// yyview.m
// 06-四邊形的五種畫法
//
// created by apple on 14-6-11.
// copyright (c) 2014年 itcase. all rights reserved.
//
#import "yyview.h"
@implementation yyview
- (void)drawrect:(cgrect)rect
{
//獲取圖形上下文
cgcontextref ctx=uigraphicsgetcurrentcontext();
//第一種畫法,通過連接固定的點繪制四邊形
// cgcontextmovetopoint(ctx, 0, 20);
// cgcontextaddlinetopoint(<#cgcontextref c#>, <#cgfloat x#>, <#cgfloat y#>);
// cgcontextaddlinetopoint(<#cgcontextref c#>, <#cgfloat x#>, <#cgfloat y#>);
// cgcontextaddlinetopoint(<#cgcontextref c#>, <#cgfloat x#>, <#cgfloat y#>);
//第二種方式:指定起點和寬高繪制四邊形
// cgcontextaddrect(ctx, cgrectmake(20, 20, 200, 100));
// //渲染
// cgcontextstrokepath(ctx);
//第三種方式:二種的兩步合并成一步。
//畫空心的四邊形
// cgcontextstrokerect(ctx, cgrectmake(20, 20, 200, 100));
// //畫實心的四邊形
// cgcontextfillrect(ctx, cgrectmake(20, 20, 200, 100));
//第四種方式(oc的方法):繪制實心的四邊形,注意沒有空心的方法
uirectfill(cgrectmake(20, 20, 200, 100));
//第五種方式:畫根線,設置線條的寬度(通過這種方式可以畫斜的四邊形)
// cgcontextmovetopoint(ctx, 20, 20);
// cgcontextaddlinetopoint(ctx, 100, 200);
// cgcontextsetlinewidth(ctx, 50);
// //注意,線條只能畫成是空心的
// cgcontextstrokepath(ctx);
}
@end
第五種方法可以畫斜的四邊形。
信紙條紋
一、前導程序
新建一個項目,在主控制器文件中實現以下幾行代碼,就能輕松的完成圖片在視圖中的平鋪。
#import "yyviewcontroller.h"
@interface yyviewcontroller ()
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
uiimage *image=[uiimage imagenamed:@"me"];
uicolor *color=[uicolor colorwithpatternimage:image];
self.view.backgroundcolor=color;
}
@end
效果:
二、實現信紙條紋的效果
利用上面的這種特性來做一個信紙的效果。
默認的view上沒有分割線,要在view上加上分割線有兩種方式:
(1)讓美工做一張專門用來做背景的圖片,把圖片設置為背景。缺點:信的長度不確定,所以背景圖片的長度也難以確定。
(2)通過一張小的圖片來創建一個顏色,平鋪實現背景效果。
第一步:生成一張以后用以平鋪的小圖片。
畫矩形。
畫線條。
第二步:從上下文中取出圖片設置為背景。黑乎乎一片?(其他地方時透明的,控制器的顏色,如果不設置那么默認為黑色的)
實現代碼:
//
// yyviewcontroller.m
// 01-信紙條紋
//
// created by 孔醫己 on 14-6-11.
// copyright (c) 2014年 itcast. all rights reserved.
//
#import "yyviewcontroller.h"
@interface yyviewcontroller ()
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
// 1.生成一張以后用于平鋪的小圖片
cgsize size = cgsizemake(self.view.frame.size.width, 35);
uigraphicsbeginimagecontextwithoptions(size , no, 0);
// 2.畫矩形
cgcontextref ctx = uigraphicsgetcurrentcontext();
cgfloat height = 35;
cgcontextaddrect(ctx, cgrectmake(0, 0, self.view.frame.size.width, height));
[[uicolor whitecolor] set];
cgcontextfillpath(ctx);
// 3.畫線條
cgfloat linewidth = 2;
cgfloat liney = height - linewidth;
cgfloat linex = 0;
cgcontextmovetopoint(ctx, linex, liney);
cgcontextaddlinetopoint(ctx, 320, liney);
[[uicolor blackcolor] set];
cgcontextstrokepath(ctx);
uiimage *image=uigraphicsgetimagefromcurrentimagecontext();
uicolor *color=[uicolor colorwithpatternimage:image];
self.view.backgroundcolor=color;
}
@end
效果:
三、應用場景
完成一個簡陋的電子書閱讀器
代碼:
//
// yyviewcontroller.m
// 01-信紙條紋
//
// created by 孔醫己 on 14-6-11.
// copyright (c) 2014年 itcast. all rights reserved.
//
#import "yyviewcontroller.h"
@interface yyviewcontroller ()
@property (weak, nonatomic) iboutlet uitextview *textview;
- (ibaction)perbtnclick:(uibutton *)sender;
- (ibaction)nextbtnclick:(uibutton *)sender;
@property(nonatomic,assign)int index;
@end
@implementation yyviewcontroller
- (void)viewdidload
{
[super viewdidload];
// 1.生成一張以后用于平鋪的小圖片
cgsize size = cgsizemake(self.view.frame.size.width, 26);
uigraphicsbeginimagecontextwithoptions(size , no, 0);
// 2.畫矩形
cgcontextref ctx = uigraphicsgetcurrentcontext();
cgfloat height = 26;
cgcontextaddrect(ctx, cgrectmake(0, 0, self.view.frame.size.width, height));
[[uicolor browncolor] set];
cgcontextfillpath(ctx);
// 3.畫線條
cgfloat linewidth = 2;
cgfloat liney = height - linewidth;
cgfloat linex = 0;
cgcontextmovetopoint(ctx, linex, liney);
cgcontextaddlinetopoint(ctx, 320, liney);
[[uicolor blackcolor] set];
cgcontextstrokepath(ctx);
uiimage *image=uigraphicsgetimagefromcurrentimagecontext();
uicolor *color=[uicolor colorwithpatternimage:image];
//self.view.backgroundcolor=color;
self.textview.backgroundcolor=color;
}
- (ibaction)perbtnclick:(uibutton *)sender {
self.index--;
self.textview.text=[nsstring stringwithformat:@"第%d頁",self.index];
catransition *ca = [[catransition alloc] init];
ca.type = @"pagecurl";
[self.textview.layer addanimation:ca forkey:nil];
}
- (ibaction)nextbtnclick:(uibutton *)sender {
self.index++;
self.textview.text=[nsstring stringwithformat:@"第%d頁",self.index];
catransition *ca = [[catransition alloc] init];
ca.type = @"pagecurl";
[self.textview.layer addanimation:ca forkey:nil];
}
@end
storyboard中的界面布局
實現的簡單效果: