一. 通过slider控制圆的缩放
1. 实现过程
新建一个项目,新建一个继承自UIView
的类,并和storyboard
中自定义的view
进行关联。
界面搭建,如图:
代码示例:
ViewController.m
文件
// // ViewController.m // TestQuartz 2D // // Created by taobaichi on 2017/3/23. // Copyright © 2017年 MaChao. All rights reserved. // #import "ViewController.h" #import <QuartzCore/QuartzCore.h> #import "newView.h" @interface ViewController () @property (weak, nonatomic) IBOutlet newView *circleView; - (IBAction)valueChange:(UISlider *)sender; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)valueChange:(UISlider *)sender { //当值改变的时候,把值传递给view,改变圆的半径 NSLog(@"---value---:%lf",sender.value); //把sender的值传递给自定义view,设置圆的半径 self.circleView.radius = sender.value; } @end
newView.h
文件
// // newView.h // TestQuartz 2D // // Created by taobaichi on 2017/3/23. // Copyright © 2017年 MaChao. All rights reserved. // #import <UIKit/UIKit.h> @interface newView : UIView @property(nonatomic, assign) float radius; @end
newView.m
文件
// // newView.m // TestQuartz 2D // // Created by taobaichi on 2017/3/23. // Copyright © 2017年 MaChao. All rights reserved. // #import "newView.h" @interface newView () @property (nonatomic, assign)float imageY; @end @implementation newView //自定义view中的圆不显示 //重写set方法,为半径赋值 -(void)setRadius:(float)radius { _radius = radius; //通知自定义的view重新绘制 [self setNeedsDisplay]; } //如果view是从xib或storyboard中创建出来的会先调用awakeFromNib方法 -(void)awakeFromNib { [super awakeFromNib]; self.radius = 20; } -(void)drawRect:(CGRect)rect { //获取图形上下文 CGContextRef context = UIGraphicsGetCurrentContext(); //绘图 //在自定义的view中画一个圆 CGContextAddArc(context, 100, 100, self.radius, 0, 2 * M_PI, 0); //设置圆的填充颜色 [[UIColor grayColor] set]; //渲染 CGContextFillPath(context); } @end
效果:
112008392957446.png
112009323741064.png
注意点: drawRect:方法不能由我们自己手动调用,只能由系统来调用 drawRect:调用的时机:当第一次显示或者一个重绘事件发生时调用 setNeedsDisplay方法:重新绘制,调用这个方法就会通知自定义的view重新绘制画面,调用`drawRect` 提示:当一个view从xib或storyboard创建出来时,会调用awakeFromNib方法
补充:
112011223118909.png
可以通过slider的value属性监听值得改变,当然也可以指定value的取值范围(这里设定为0 ~ 100)
二.刷帧效果
说明:把雪花状的图片绘制到view
上,实现图片中下落的效果
1. 实现代码
// // newView.m // TestQuartz 2D // // Created by taobaichi on 2017/3/23. // Copyright © 2017年 MaChao. All rights reserved. // #import "newView.h" @interface newView () @property (nonatomic, assign)float imageY; @end @implementation newView -(id)initWithCoder:(NSCoder *)aDecoder { //请注意这里一定要先初始化父类的构造方法 if (self = [super initWithCoder:aDecoder]) { NSLog(@"initWithCoder: "); //NSTimer一般用于定时的更新一些非界面上的数据,告诉多久调用一次 //使用定时器,使用该定时器会出现卡顿现象 //[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateImage) userInfo:nil repeats:YES]; //ACDisplayLink刷帧,默认每秒刷新60次 //该定时器创建之后,默认是不会执行的,需要把它加载到消息循环中 CADisplayLink * display = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateImage)]; [display addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } return self; } -(void)updateImage { //使用该方法重绘画面 [self setNeedsDisplay]; } -(void)awakeFromNib { [super awakeFromNib]; NSLog(@"awakeFromNib"); } -(void)drawRect:(CGRect)rect { //把图片绘制到view上 //每次调用该方法对画面进行重绘,imageY的值就+5 self.imageY += 5; //当雪花超出屏幕的时候,让图片从头开始降落 if (self.imageY > rect.size.height) { self.imageY = 0; } UIImage * image = [UIImage imageNamed:@"snow"]; [image drawAtPoint:CGPointMake(0, self.imageY)]; UIImage * image2 = [UIImage imageNamed:@"me"]; [image2 drawAtPoint:CGPointMake(80, self.imageY + 20)]; } @end
实现效果:
112015196088547.png
112015590611761.png
2. 重要说明
- 下面两个方法的调用顺序
-(void)awakeFromNib -(id)initWithCoder:(NSCoder *)aDecoder
提示:如果
view
是从xib
或storyboard
中创建可以调用awakeFromNib
方法归档,从文件创建view
,其实会先调用initWithCoder
这个方法,xib
和storyboard
也是文件
上面两个方法,
-(id)initWithCoder:(NSCoder *)aDecoder
会先调用,实现该方法需要实现NSCoding
协议,由于创建的UIView
默认就已经实现了该协议。
可以进入到头文件查看:
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, CALayerDelegate>
运行新建的程序,通过打印可以验证上面两个方法的调用顺序
2017-03-23 18:24:28.560 TestQuartz 2D[9196:314708] initWithCoder: 2017-03-23 18:24:28.561 TestQuartz 2D[9196:314708] awakeFromNib
两个定时器
- 第一个:
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateImage) userInfo:nil repeats:YES]; 说明:`NSTimer`一般用于定时的更新一些非界面上的数据,告诉多久调用一次,
- 第二个:
CADisplayLink * display = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateImage)]; [display addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
说明: CADisplayLink
刷帧,默认每秒刷新60次,该定时器创建之后,默认是不会执行的,需要把它加载到消息循环中