用UIBezierPath类自定义视图

课题:如何来自定义一个UIView呢?UIKit提供给我们很强大的UIView及它子类,但这些都不能满足时,我们就应该自定义一个视图。

  • 创建一个工程并创建一个继承于UIView的自定义视图类KNZCustomView
Snip20160928_2.png

Xcode已经提供一个带- (void)drawRect:(CGRect)rect方法的模板,我们只能在这个方法中去自定义视图,参数rect就是你视图绘图范围。

  • 在ViewController.m文件中创建一个自定义视图
    <code>
    #import "ViewController.h"
    #import "KNZCustomView.h"
    @interface ViewController ()
    </br>@end
    @implementation ViewController
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    //创建一个窗口大小的自定义KNZCustomView对象customView,并设置它背景颜色为白色
    KNZCustomView *customView = [[KNZCustomView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    customView.backgroundColor = [UIColor whiteColor];
    self.view = customView;
    }
    @end
    </code>
    运行一下,白白一片,啥都没有,因为你还没有开始画图呀!


    Snip20160928_4.png

我们先来画一条直线

  1. 在KNZCustomView.m文件中,先创建一个UIBezierPath路径对象path
    <code>UIBezierPath *path = [[UIBezierPath alloc]init];</code>
    路径就是你画图的想法,然后定义直线的起始点(100,100)
    <code>[path moveToPoint:CGPointMake(100, 100)];</code>
    两个点决定一条直线,用另外一个点确定一条直线:
    <code>[path addLineToPoint:CGPointMake(200, 200)]; </code>
    我们已经想好画一条直线的想法-路径了,但现在运行的话,还是什么都没有,因为你现在只有想法,你还没去画出来。
    我们开始将这个想法画出来吧。
    <code>[path stroke];</code>
Snip20160928_6.png

运行结果:


Snip20160928_7.png

终于看到有直线了,又细又黑的.......但我想要是一条比较粗的红色的直线呢?
那我们就要在画这个想法时,再添加多一点想法了
<code>
path.lineWidth = 10;
[[UIColor redColor]setStroke];
[path stroke];
</code>

关于更加多的想法,你可以看我翻译的UIBezierPath类文章中的属性和方法:http://www.jianshu.com/p/5f9e047865df

再运行

Snip20160928_8.png

一条又红又粗的直线就画出来了!Bingo!

使用UIBezierPath思维方式就是先创建一个UIBezierPath对象,也就是画图的想法,这个时候想法为空。然后对这个路径添加画图的想法:画线段?画圆?画弧?画矩形?什么颜色?多宽?是描边还是填充?详细内容还得看UIBezierPath类中的说明。

我们先来画一个内切圆形吧!

  1. 在KNZCustomView.m文件中,用UIBezierPath的类方法+ bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:快速创建路径对象path,里面为一个画圆的想法。
Snip20160928_9.png

要求输入五个实参:圆的圆心、半径、开始角度、终止角度、描绘方向。

2.圆心为窗口中心点,半径为内切圆时半径(不是窗口width就是height的长度的一半),开始角度为0,终止角度为2倍的M_PI(角度单位为弧度,M_PI为一个π,一个圆形为2π),描绘方向为顺时针方向(设置YES为顺时针,NO为逆时针)。
<code>
CGPoint center =CGPointMake(rect.size.width*0.5,rect.size.height *0.5);
//MIN(A,B)C语言标准函数,求A、B最小那个
CGFloat radius = MIN(rect.size.width, rect.size.height) * 0.5;
CGFloat startAngle = 0 ;
CGFloat endAngle = M_PI * 2;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
</code>
已经想好怎么去画一个圆了,我们把它画出来吧!
<code>[path stroke];</code>
运行


Snip20160928_10.png

我想将这个圆形全部用黄色填充,并不是只画个形状出来而已,那我们就将stroke改为fill就可以简单地实现了。
<code>
[[UIColor yellowColor]setFill];
[path fill];
</code>
运行

Snip20160928_11.png

整个画图代码中,没有出现其它文章写的难懂的图形上下文,因为UIBezierPath这个类已经帮你封装好了,你只要stroke或fill一下,就可以将path对象画出来,是不是超简单呢?
苹果就在将复杂冗余的低级类封装成高级类让我们去开发app,让我们专注于app用户体验方面,而不是学习难懂的底层框架技术。

用UIBezierPath类画一个复杂一点点的自定义View

说复杂,也不是很复杂,放心,很容易懂的

还是在上一篇自定义视图基础上画,先创建一个UIBezierPath路径对象
<code>UIBezierPath *path = [[UIBezierPath alloc]init];</code>
接着我想画一个外接圆,然后再画一系列半径每次减少20的同心圆。
外接圆半径maxRadius
<code>
CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);//圆心
CGFloat maxRadius = hypot(rect.size.width, rect.size.height) * 0.5;//圆半径</code>

hypot(A,B)为C语言函数,给出A、B求直角三角形斜边长

画一系列同心圆,第一个想到用for循环函数,每一次画的圆半径为radius,每次画完半径就减少20,直到半径小于0才结束
<code>
for (int radius = maxRadius; radius > 0; radius -= 20) {
[path addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI *2 clockwise:YES];
}
</code>
画出来
<code>[path stroke];</code>

Snip20160928_12.png

运行


Snip20160928_13.png

感觉已经画出来了,但那个线是怎么回事啊??
原因是你每次画一个圆半径减少20,你没有告诉path,我要从新的点开始画,他就是自动生成从上一个圆终点到下一个圆起始点的直线。
解决这个问题很简单,你每次还要告诉下一个圆,你要从哪个点开始画就行了。
<code>[path moveToPoint:CGPointMake(center.x + radius, center.y)];</code>

Snip20160928_14.png

运行

Snip20160928_15.png

看到这个同心圆,晕了吗?给它加粗点吧!还要设为红色!


Snip20160928_17.png

再次运行

Snip20160928_18.png

好吧!用UIBezierPath类画图就是这么简单!!

我写的这个文章只是一个入门思想介绍,交流最重要的是让对方明白就好了,我自己在看技术文章时,发现你们虽然自己学懂了,但没让其他人都看懂。能让一个小学生都能看懂的文章,才能让知识传播得更远。关于更加多的画图方法请查看我翻译的UIBezierPath类资料。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容