iOS开发UI篇 - Quartz 2D简单使用

2017-03-23  本文已影响17人  码代码的小马

一. 通过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
  1. 重要说明
-(void)awakeFromNib

-(id)initWithCoder:(NSCoder *)aDecoder

提示:如果view是从xibstoryboard中创建可以调用awakeFromNib方法归档,从文件创建view,其实会先调用initWithCoder这个方法,xibstoryboard也是文件

上面两个方法,-(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次,该定时器创建之后,默认是不会执行的,需要把它加载到消息循环中

上一篇下一篇

猜你喜欢

热点阅读