1.矩阵操作
1.1首先新建一个project,然后搭建界面。首先自定义一个view(创建一个类让其继承自Uiview,然后在storyboard中拖一个view,并改其名称)
1.2代码演示使用
1.2.1未旋转之前
#import "MJView.h"
@implementation MJView
/**
渐变色
虚线
pattern
blend
.....
.....
阴影
*/
- (void)drawRect:(CGRect)rect
{
//获取图形上下文对象
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 将ctx拷贝一份放到栈中
CGContextSaveGState(ctx);
// CGContextRotateCTM(ctx, M_PI_4 * 0.3); //图像旋转
// CGContextScaleCTM(ctx, 0.5, 0.5);//缩放
// CGContextTranslateCTM(ctx, 0, 150); //平移 往下面走150
//绘制一个矩形
CGContextAddRect(ctx, CGRectMake(10, 10, 50, 50));
//绘制一个椭圆
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 100, 100));
//绘制一根线段
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddLineToPoint(ctx, 200, 250);
//渲染
CGContextStrokePath(ctx);
//将栈顶上下文出栈,替换掉当前的上下文对象(下面所画得椭圆和线段都不会受到上面的影响
CGContextRestoreGState(ctx);
// 矩阵操作
// CGContextScaleCTM(ctx, 0.5, 0.5); //正确用法应该放到前面
CGContextStrokePath(ctx);
}
@end
以上代码运行结果为:
1.2.2旋转平移线段和椭圆(将改变状态的代码打开)
#import "MJView.h"
@implementation MJView
/**
渐变色
虚线
pattern
blend
.....
.....
阴影
*/
- (void)drawRect:(CGRect)rect
{
//获取图形上下文对象
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 将ctx拷贝一份放到栈中
CGContextSaveGState(ctx);
CGContextRotateCTM(ctx, M_PI_4 * 0.3); //图像旋转
CGContextScaleCTM(ctx, 0.5, 0.5);//缩放
CGContextTranslateCTM(ctx, 0, 150); //平移 往下面走150
//绘制一个椭圆
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 100, 100));
//绘制一根线段
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddLineToPoint(ctx, 200, 250);
//渲染
CGContextStrokePath(ctx);
CGContextRestoreGState(ctx);
//绘制一个矩形
CGContextAddRect(ctx, CGRectMake(10, 10, 50, 50)); //将栈顶上下文出栈,替换掉当前的上下文对象(下面所画得椭圆和线段都不会受到上面的影响
// 矩阵操作
// CGContextScaleCTM(ctx, 0.5, 0.5); //正确用法应该放到前面
CGContextStrokePath(ctx);
}
@end
以上代码运行结果为
2.官方demo下载学习
2.1.打开文档
2.2搜索Quartz2D
搜索到Quartz2D后点击
Open Project
即可自动下载
这个时候它会默认下载到'下载'当中“,然后打开运行即可学习到权威的demo,运行效果如下,里面有很多demo,进入即可学习
3.裁剪
首先上一份代码
#import "MJClipView.h"
@implementation MJClipView
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
//讲ctx拷贝一份放到栈中
// CGContextSaveGState(ctx);
// 0.画圆
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50));
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 14px; font-family: 'Heiti SC Light'; color: rgb(151, 20, 31);"><span style="font-family: Menlo; color: rgb(0, 0, 0);"> </span><span style="font-family: Menlo;">// </span>裁剪(将当前上下文的形状按照上面画得那个圆的形状裁剪出来,以后添加的内容只能放到这个形状里面去)</p>
CGContextClip(ctx);
CGContextFillPath(ctx);
// 1.显示图片
UIImage *image = [UIImage imageNamed:@"me"];
[image drawAtPoint:CGPointMake(100, 100)];
//将栈顶上下文出栈替换当前上下文
// CGContextRestoreGState(ctx);
//画一个矩形
CGContextAddRect(ctx, CGRectMake(0, 0, 50, 50));
CGContextFillPath(ctx);
}
@end
以上代码运行结果如下
由上可以看书当 设置了裁剪之后,则后面的内容都只能在所裁剪出来的区域内显示
只有设置图形上下文后,则后面的内容才不会受影响(打开图形上下文的代码后)
4.重绘(刷帧)
首先新建一个project,然后自定义一个view
再拖一个 Horizontal Slider 控件(如上图)
代码:
控制器.m文件
#import "MJViewController.h"
#import "MJView.h"
/**
* 实现逻辑:当拖动滑块的时候将滑块的值传递给radius属性,然后radius属性从新为半径,刷新图形
*/
@interface MJViewController ()
- (IBAction)sizeChange:(UISlider *)sender;
@property (weak, nonatomic) IBOutlet MJView *circleView;
@end
@implementation MJViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sizeChange:(UISlider *)sender {
self.circleView.radius = sender.value; //将滑块的值传递给半径
}
@end
自定义view .m文件
#import "MJView.h"
@implementation MJView
- (void)setRadius:(float)radius
{
_radius = radius;
[self setNeedsDisplay]; //调用这个方法的时候就会调用drawRect:这个方法
}
/**
* 默认只会在view第一次显示的时候调用(只能由系统自动调用, 不能手动调用)
*/
- (void)drawRect:(CGRect)rect
{
NSLog(@"drwract---%f", self.radius);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddArc(ctx, 125, 125, self.radius, 0, M_PI * 2, 0);
CGContextFillPath(ctx);
}
@end
运行结果(当拖动滑块的时候圆就随着变化)
5.动画
5.1创建一个project,然后自定义一个继承自UIView的view,并且让这个自定义的view成为控制器的view
5.2代码实现
#import "MSnowView.h"
@interface MSnowView()
@property (nonatomic, assign) CGFloat snowY;
@end
@implementation MSnowView
/**
* 当一个view从storyboard中创建的话就会调用这个方法(系统自动调用)
*/
- (void)awakeFromNib
{ //创建定时器
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];//调用这个setNeedsDisplay方法就会重新调用drawRect:这个方法
//添加到主消息循环 启动 (默认一秒刷新60次)
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
//[NSTimer scheduledTimerWithTimeInterval:0.1 target:selfselector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
//每隔0.1秒就刷新一次(每隔0.1秒就调用setNeedsDisplay一次)
}
/**
* 默认只会在view第一次显示的时候调用(只能由系统自动调用, 不能手动调用) ,只有调用setNeedsDisplay这个方法之后才会再次调用drawRect:这个方法
*
* @param rect <#rect description#>
*/
- (void)drawRect:(CGRect)rect
{
self.snowY+=5;
if (self.snowY >= rect.size.height) {
self.snowY = -100;
}
UIImage *image = [UIImage imageNamed:@"snow.jpg"];
[image drawAtPoint:CGPointMake(0, self.snowY)];
}
@end