用UIBezierPath类自定义视图

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

  • 创建一个工程并创建一个继承于UIView的自定义视图类KNZCustomView
用UIBezierPath类自定义视图_第1张图片
Snip20160928_2.png

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

  • 在ViewController.m文件中创建一个自定义视图

    #import "ViewController.h"
    #import "KNZCustomView.h"
    @interface ViewController ()

    @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

    运行一下,白白一片,啥都没有,因为你还没有开始画图呀!


    用UIBezierPath类自定义视图_第2张图片
    Snip20160928_4.png

我们先来画一条直线

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

运行结果:


用UIBezierPath类自定义视图_第4张图片
Snip20160928_7.png

终于看到有直线了,又细又黑的.......但我想要是一条比较粗的红色的直线呢?
那我们就要在画这个想法时,再添加多一点想法了

path.lineWidth = 10;
[[UIColor redColor]setStroke];
[path stroke];

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

再运行

用UIBezierPath类自定义视图_第5张图片
Snip20160928_8.png

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

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

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

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

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

2.圆心为窗口中心点,半径为内切圆时半径(不是窗口width就是height的长度的一半),开始角度为0,终止角度为2倍的M_PI(角度单位为弧度,M_PI为一个π,一个圆形为2π),描绘方向为顺时针方向(设置YES为顺时针,NO为逆时针)。

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];

已经想好怎么去画一个圆了,我们把它画出来吧!
[path stroke];
运行


用UIBezierPath类自定义视图_第7张图片
Snip20160928_10.png

我想将这个圆形全部用黄色填充,并不是只画个形状出来而已,那我们就将stroke改为fill就可以简单地实现了。

[[UIColor yellowColor]setFill];
[path fill];

运行

用UIBezierPath类自定义视图_第8张图片
Snip20160928_11.png

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

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

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

还是在上一篇自定义视图基础上画,先创建一个UIBezierPath路径对象
UIBezierPath *path = [[UIBezierPath alloc]init];
接着我想画一个外接圆,然后再画一系列半径每次减少20的同心圆。
外接圆半径maxRadius

CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);//圆心
CGFloat maxRadius = hypot(rect.size.width, rect.size.height) * 0.5;//圆半径

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

画一系列同心圆,第一个想到用for循环函数,每一次画的圆半径为radius,每次画完半径就减少20,直到半径小于0才结束

for (int radius = maxRadius; radius > 0; radius -= 20) {
[path addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI *2 clockwise:YES];
}

画出来
[path stroke];

用UIBezierPath类自定义视图_第9张图片
Snip20160928_12.png

运行


用UIBezierPath类自定义视图_第10张图片
Snip20160928_13.png

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

用UIBezierPath类自定义视图_第11张图片
Snip20160928_14.png

运行

用UIBezierPath类自定义视图_第12张图片
Snip20160928_15.png

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


用UIBezierPath类自定义视图_第13张图片
Snip20160928_17.png

再次运行

用UIBezierPath类自定义视图_第14张图片
Snip20160928_18.png

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

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

你可能感兴趣的:(用UIBezierPath类自定义视图)