QuartZ2D __ 简单用法 1

一. 简单做一个画板

1. 建立一个UIView类

2. 在.m里建立一个延展

3. 分别定义一个起点, 一个终点的结构体属性 . 在建立一个存储路径的数组

@interface DrawView ()
{
    CGPoint _startPoint;
    CGPoint _endPoint;
}

@property (nonatomic, strong) NSMutableArray *pathArray;

@end

4. 懒加载数组

- (NSMutableArray *)pathArray
{
    if (_pathArray == nil) {
        _pathArray = [NSMutableArray array];
    }
    return _pathArray;
}

5. 开始绘制

(1) 起点

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 获取起点
    _startPoint = [[touches anyObject] locationInView:self];

    // 创建贝瑟尔路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    // 起点
    [path moveToPoint:_startPoint];

    // 添加到数组中
    [self.pathArray addObject:path];

}

(2) 终点

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    _endPoint = [[touches anyObject] locationInView:self];

    // 终点
    UIBezierPath *path = [self.pathArray lastObject];

    [path addLineToPoint:_endPoint];

    [self setNeedsDisplay];
}

6. 重写  - (void)drawRect:(CGRect)rect 方法

- (void)drawRect:(CGRect)rect {
    // Drawing code

    for (UIBezierPath *path in self.pathArray) {
        // 设置颜色
        [[UIColor orangeColor] set];
        // 设置粗度
        path.lineWidth = 10;
        // 渲染
        [path stroke];
    }

}

二. 绘制饼状图

注 : 为了好看, 我随即分成了大小颜色都不同的99份

代码实现

#import "DrawView.h"

#define kcolor arc4random()% 256 / 255.0

@implementation DrawView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code

    NSMutableArray *array = [NSMutableArray array];
    int sum = 0;
    for (int i = 1; i< 100; i ++) {
        int num = arc4random()% 100 ;
        sum += num;
        NSNumber *number = [NSNumber numberWithInt:num];
        [array addObject:number];
    }
    // 记录起点和终点
    CGFloat start = 0;
    CGFloat end = 0;
    // 遍历数据
    for (NSNumber *num in array) {

        end = num.floatValue / sum * M_PI * 2;

        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:start endAngle:start + end clockwise:YES];
        // 关闭路径
        [path addLineToPoint:CGPointMake(150, 150)];

        [[UIColor colorWithRed:kcolor green:kcolor blue:kcolor alpha:1] set];
        [path closePath];
        [path fill];
        start += end;

    }

@end

 

三. 截图用法

1. 首先要有一个imageView, 所以在ViewContorller先建立一个UIImageView的属性 将背景的图片设置出来

2. 建立一个继承自UIView的类

3. 在这个UIView类.m里实现截图 (.h中写了一个block块用于传递路径)

.h 代码实现

// 传递路径
typedef void(^block)(UIBezierPath *p);

@interface MyView : UIView

@property (nonatomic, copy) block myblock;

@end

.m 代码实现

#import "MyView.h"

@interface MyView ()

// 保存路径
@property (nonatomic, strong) NSMutableArray *pathArray;

@end

@implementation MyView

- (NSMutableArray *)pathArray
{
    if (! _pathArray) {
        _pathArray = [NSMutableArray array];
    }
    return _pathArray;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1. 获取起始点 并且创建路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:[[touches anyObject] locationInView:self]];

    // 2. 装入数组
    [self.pathArray addObject:path];

}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1. 获取终点 (不止一个)
    UIBezierPath *path = [self.pathArray lastObject];
    [path addLineToPoint:[[touches anyObject] locationInView:self]];

    // 2. 调用drawrect
    [self setNeedsDisplay];

}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 封闭路径
    UIBezierPath *path = [self.pathArray lastObject];
    [path closePath];

    [self setNeedsDisplay];
    // 调用block路径
    self.myblock(path);
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    for (UIBezierPath *path in self.pathArray) {
        path.lineWidth = 2;
        [[UIColor orangeColor] set];
        [path stroke];

    }
}

@end

4. 在ViewController中中回调路径

#import "ViewController.h"

#import "MyImageView.h"

#import "MyView.h"

@interface ViewController ()

@property (nonatomic, strong) UIImageView *imageView;

@property (nonatomic, strong) MyView *myView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 获取图片
    // __block全局区
   __block UIImage *image = [UIImage imageNamed:@"0"];
    self.imageView = [[UIImageView alloc] initWithImage:image];
    _imageView.frame = CGRectMake(7, 160, image.size.width, image.size.height);
    [self.view addSubview: _imageView];

    self.myView = [[MyView alloc] initWithFrame:self.imageView.frame];
    _myView.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0];
    [self.view addSubview:_myView];

    // 剪切

    __weak typeof(self) weakSelf = self;
    _myView.myblock = ^(UIBezierPath *p){

        // 获取上下文
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        // 路径
        UIBezierPath *path = p;
        // 剪切
        [path addClip];
        // 绘制
        [image drawAtPoint:CGPointZero];
        // 获取剪切后的图片
        image = UIGraphicsGetImageFromCurrentImageContext();
        // 结束上下文
        UIGraphicsEndImageContext();
        // 给imageView赋值
        weakSelf.imageView.image = image;

    };
}

@end
时间: 2024-11-20 20:32:11

QuartZ2D __ 简单用法 1的相关文章

iOS block-base 动画简单用法+关键帧动画设置线性变化速度的问题

本文转载至 http://www.tuicool.com/articles/aANBF3m 时间 2014-12-07 20:13:37  segmentfault-博客原文  http://segmentfault.com/blog/alan/1190000002411296 iOS的各种动画相漂亮,相信这是吸引很多人买iPhone的原因之一.不仅如此,这还是吸引我做iOS开发的一大原因,因为在iOS上给界面实现一些像样的动画实在是太轻松了! 这里就介绍一下iOS的block-based an

Android WIFI 简单用法

随着Wifi的普及,在开发App的时候对wifi的考虑越来越多了.例如程序的升级在wifi下可以省很多流量,在通信软件中的视频通话.可以实现高画质的传输等等,Android提供了WifiManager类来帮助开发者们管理Wifi.下面就简单来说一下WifiManager的简单用法把. 权限: 为了使用WfiManager 我们需要在Androidmanifest.xml 加入权限: //本例中使用了前两个.具体请按照需要添加权限. <uses-permission android:name=&quo

Android中资源文件中的字符串数组string-array简单用法

在Android中,用string-array是一种简单的提取XML资源文件数据的方法. 例子如下: 把相应的数据放到values文件夹的strings.xml文件里,或是其他自定义的xml中都可以,以下操作方法相同. <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="sports"> <item>足球<

expect简单用法

1 #!/usr/expect/bin/expect -f 2 3 4 set loginuser [lrange $argv 0 0] 5 set loginpass [lrange $argv 1 1] 6 set ipaddr [lrange $argv 2 2] 7 set port [lrange $argv 3 3] 8 set timeout [lrange $argv 4 4] 9 set from [lrange $argv 5 5] 10 set to [lrange $ar

Tcpdump 的简单用法

Tcpdump 的简单用法 tcpdump是Linux命令行下使用最广泛的网络分析工具,运行的时候会将网卡运行在混杂模式下,需要root权限才能执行 下面是几个比较常见的参数: -w  保持到指定的文件 -i  指定监听的网卡,缺省显示第一块网卡 -nn 以IP方式显示host -v  显示详细信息 -s  指定数据包大小,缺省是65535 -t  不显示时间 ,缺省是显示时间戳 -c  获取数据包数量,缺省不限制,需要用Ctrl+c来终止 下面是关于命令关键字的说明 1.主要包括host,ne

C++ double转string类型以及MFC控件简单用法

这两天项目需要,测试c++库里面内容.生成jar再给Android调用.我没有学过C++,现在开始记录C++简单用法.测试时候一般都是使用mfc程序来测试,要输入值,显示结果吗.我用的编译环境vs2008. 一.double 转string #include <string> CString strResultx; strResultx.Format(_T("x:%.4f\n"), 89.7887878); 转换结果还是放在strResultx 2.两个字符串相连 CStr

vB SendMessage API 简单用法

vB SendMessage API 简单用法 1. 在Windows编程中,向文本框控件.列表控件.按钮控件等是我们最常接触的控件了.但是在VB中这些控件有时无法实现我们的需要.在这时,我们只要简单的利用Windows API函数就可以扩充这些控件的功能了.顾名思义,SendMessage函数就是向窗口(这里的窗口指的是向按钮.列表框.编辑框等具有hWnd属性的控件)发送消息的函数,该函数的定义如下:Declare Function SendMessage Lib "user32"

java中Object.equals()简单用法

/* equals()方法默认的比较两个对象的引用! */ class Child { int num; public Child(int x){ num = x; } //人文的抛出运行时异常的好处是:可以自定义错误信息! /*public boolean equals(Object o) throws ClassCastException{ if(!(o instanceof Child)) throw new ClassCastException("中文提示:类型错误"); Ch

UIDatePicker的简单用法

// 初始化UIDatePickerUIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 200, 320, 216)];// 设置时区[datePicker setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];// 设置当前显示时间[datePicker setDate:tempDate animated:YES];// 设置显示最大时间