简单的绘图思想及绘图案例

绘制饼状图主要思想

循环添加

主要计算结束弧度  数据的本分比*360 + 开始弧度


开始绘制圆弧,链接中心,设置随机色,fill填充  最后很重要的异步就是数据转换,把结束弧度赋值给开始弧度。

参考代码

- (void)drawRect:(CGRect)rect {

  


    NSArray *data = @[ @30, @15, @5 , @17 , @3, @10, @20];

    

    CGFloat radius = MIN(self.bounds.size.width/2, self.bounds.size.height/2);

    

    CGFloat start = 0;

    CGFloat end = 0;

CGPoint centerP = CGPointMake(rect.size.width/2, rect.size.height/2);

    for (int i = 0; i < data.count; i++) {

        //主要是计算结束弧度,数据的百分数*360 加上开始弧度

        end = [data[i]floatValue ]/100 * (2 * M_PI) + start;

        

        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:centerP radius:radius startAngle:start endAngle:end clockwise:YES];

        

        [path addLineToPoint:centerP];

        

        //添加颜色

        [[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0]set ];

        

        [path fill];

        

#pragma mark 这是很重要的角度转换

        start = end;

    }

}



柱状图实现思想

主要计算 x h

w 就是平均宽度    rect /(数据数量的2倍-1);

循环添加矩形

x 就是 平均宽度 * 2 * i

h 就是百分比*矩形的高度

y rect - h;

实例代码

- (void)drawRect:(CGRect)rect {

    

    NSArray *data = @[@300, @150.65, @55.3, @507.7, @95.8, @700, @650.65];

    

    //设置宽度

    CGFloat w = rect.size.width / (data.count * 2 - 1);

    

    for (int i = 0; i < data.count; i++) {

     

        //x就等于 2*w*i

        CGFloat x = w * i * 2;

        

        //高度就等于 百分比 * rect的高度

        CGFloat h = [data[i] floatValue]/1000 * rect.size.height;

        

        //y 就等于屏幕的高度 - 他的高度

        CGFloat y = rect.size.height  - h;

        

        UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];

        

        [[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0]set ];

        

        [path fill];

     }

    

}



//自定义下载进度

主要计算结果弧度


给veiw中添加一个记录数据的属性

在storyboard中 连接  属性 slider 和 自定义的View(他里面设置一个记录数据的属性)


把sliderl接一个方法  在里面用它的Value给view的属性赋值


在draw中绘制圆弧

看需求在哪个开始绘图


重写记录属性的参数,并进行重绘 ,就能实现随着slider变化了


如果想显示下载多少,可以用一个label来显示,用懒加载添加label

记得用strong,

设置frame时设置成view一样大,字中间显示

在重写记录数据的那个方法中计算它的百分比 就用,数据*100就可以


实例代码

- (void)drawRect:(CGRect)rect {

    // Drawing code

    

    //创建路径

    

    CGPoint point = CGPointMake(rect.size.width/2, rect.size.height/2);

    

    CGFloat radius = MIN(rect.size.width/2, rect.size.height/2);

    

    CGFloat statr = -M_PI_2;

    

    CGFloat end = 2 * M_PI * self.count + statr;

    

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:point radius:radius startAngle:statr endAngle:end clockwise:YES];

    

    

    [path addLineToPoint:point];

    

    [[UIColor redColor] set];

    

    [path fill];

    

    

   UIBezierPath *path1 =  [UIBezierPath bezierPathWithArcCenter:point radius:radius - 10 startAngle:statr endAngle:end clockwise:YES];

    

    [path1 addLineToPoint:point];

    [self.backgroundColor set];

    

    [path1 fill];

    

}


给属性赋值

- (IBAction)changeVale:(UISlider *)sender {

    

    self.xlImageView.count = sender.value;

}


//属性得用strong 懒加载

- (UILabel *)label{


    if (_label == nil) {

        

        _label = [[UILabel alloc]init];

        _label.textColor = [UIColor brownColor];

        

        _label.font = [UIFont systemFontOfSize:25.f];

        

        _label.textAlignment = NSTextAlignmentCenter;

        

        [self addSubview:_label];

        

        

    }

    return _label;

}


//设置frame

- (void)layoutSubviews

{


    [super layoutSubviews];

    

    self.label.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);

    

}

//重写count

- (void)setCount:(CGFloat)count

{

    _count = count;

    

    //设置内容

    self.label.text = [NSString stringWithFormat:@"%.2f%%",self.count * 100];

    

    [self setNeedsDisplay];

    

}





//自定义

自定义图片框

声明一个继承UIVIew的类

声明一个image的属性

在 drawRect中绘制image

重写image,并进行重绘

这就完成了自定义imageView。就可以用他进行添加图片。


示例

.h中有个image属性

- (void)setImage:(UIImage *)image

{

    _image = image;

    

    //重绘

    [self setNeedsDisplay];


}


- (void)drawRect:(CGRect)rect {

    

    [self.image drawInRect:rect];

    

}


引用头文件,就可以像UIImageView一样使用了




用触摸事件和绘图    小案例实现思想

案例1.简易画板的实现思想


1.>在touchesBegan中根据触摸对象获取当前的点

开启划线路径,把当前点击的点设置为线的起始点。


在touchesMoved中也根据触摸对象获取当前点击的点,把他设置为线的线段。在里面执行重绘。


在drawRect中渲染。就能把线绘画出来,但是发现,只能存储一个根线。

2.>解决办法,把线都存储到数组中,在touchesBegan中存储线的起点,在touchesMoved中根据数组的有序的性质,获取它最后一个元素添加线条。所以修改他添加线的方法。

因为存储在数组中,所以在drawRect中forin循环 (什么类型)BezierPath *path in  (数组中);这样就可以绘制多条线段了。

3.>线宽根据slider来设置,连线在viewDidLoad中,slider连个属性(主要为了给线宽设置一个初始值)和方法(把自身传过来,方便用他自身value的属性),把绘制的UIView的类连个属性,在它里面设置一个熟悉,用来接收slider的值。(CGFloat类型)

 

在touchesBegan中设置线宽,如果早drawRect中设置了线宽,那么一画线的线段,那么线宽都会变成当前的线宽


4.>实现点击按钮中的颜色改变线的颜色

在继承UIVIew中在添加一个lineColor的属性,把按钮连线到storyboard中,把按钮自己传过来。设置属性的颜色为按钮的背景颜色。(按钮的方法都可以连接到一个方法中);因为颜色设置有些特殊,所以自定义一个BezierPath 在里面设置一个属性lineColor

这样的话就把前面的BezierPath 都改成自定义的BezierPath

在颜色按钮中设置Views中颜色的属性,在touchesBegan中给自定义的颜色属性赋值,(因为是自定义的所以在drawRect中用路径设置线的颜色)这样颜色就可以根据按钮的颜色来设定了


清屏

在UIView中来一个方法,移除数组中所有元素,然后在item的方法中,调用这个方法就行。

回退

和清屏差不多,移除最后一个数组元素就行

然后调用方法

橡皮擦

设置成背景颜色,然后在item的方法中调用就可以了


保存就是截屏然后存相册或者沙河


代码

继承UIView

.h

@interface XLView : UIView

@property (nonatomic,assign) CGFloat lineWinth;

@property (nonatomic,strong) UIColor *lineColor;


- (void) clean;


- (void) banck;


- (void) eraser;

@end

.m

#import "XLView.h"

#import "XLBezierPath.h"


@interface XLView ()

@property (nonatomic,strong) XLBezierPath *path;

@property (nonatomic,strong) NSMutableArray *paths;


@end




@implementation XLView


- (NSMutableArray *)paths

{

    if (_paths == nil) {

        

        _paths = [NSMutableArray array];

    }

    return _paths;

}




//手指按下

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    //获取触摸对象

    UITouch *touch = touches.anyObject;

    

    //根据触摸对象获取当前点击的点

    CGPoint locp = [touch locationInView:touch.view];

    

    //开启路径

    self.path = [XLBezierPath bezierPath];

    

    //当前点击的点就是开始的点

    [self.path moveToPoint:locp];

    

    //设置线宽

    self.path.lineWidth = self.lineWinth;

    

    

    //设置颜色

    self.path.line9Color = self.lineColor;

    

    //保存到数组

    [self.paths addObject:self.path];


}


//手指移动

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    //获取触摸对象

    UITouch *touch = touches.anyObject;

    

    //根据触摸对象获当前点

    CGPoint currentP = [touch locationInView:touch.view];

    

    //划线

    [[self.paths lastObject] addLineToPoint:currentP];

    

    //重绘

    [self setNeedsDisplay];

    

    

}


//手指抬起

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{


}


- (void)drawRect:(CGRect)rect {

   

//    [self.path stroke];

    

    //既然在数组中,要绘制那就要绘制所有的,那就循环绘制

    for (XLBezierPath *path in self.paths) {

        

        //设置连接样式

        path.lineJoinStyle = kCGLineJoinRound;

        

        //设置线的头样式

        path.lineCapStyle = kCGLineCapRound;

        

        //设置颜色

        [path.line9Color set];

        

         [path stroke];

    }

}


- (void) clean

{

    [self.paths removeAllObjects];

    [self setNeedsDisplay];

}


- (void) banck

{

    [self.paths removeLastObject];

    [self setNeedsDisplay];

}


- (void) eraser

{

    self.lineColor = self.backgroundColor;

    [self setNeedsDisplay];

}



自定义的

@interface XLBezierPath : UIBezierPath

@property (nonatomic,strong) UIColor *line9Color;


@end


storyboard中

@interface ViewController ()

@property (weak, nonatomic) IBOutlet XLView *xlView;


@property (weak, nonatomic) IBOutlet UISlider *slider;

@end


@implementation ViewController


//lView中的lineWinth赋值

- (IBAction)changeVslue:(UISlider *)sender

{

    self.xlView.lineWinth = sender.value;

}


- (void)viewDidLoad {

    [super viewDidLoad];


    //赋一个初始值


    self.xlView.lineWinth = self.slider.value;

}



- (IBAction)btcClick:(UIButton *)sender

{

    self.xlView.lineColor = sender.backgroundColor;

    

}


- (IBAction)cleanBtn:(id)sender

{

    [self.xlView clean];

}

- (IBAction)eraserBtnClick:(id)sender

{

    [self.xlView eraser];

}


- (IBAction)backBtnClick:(id)sender

{

    [self.xlView banck];

}



- (BOOL)prefersStatusBarHidden

{

    return YES;

}

- (IBAction)saver:(id)sender {

    

    //开启图形上下文路径

    UIGraphicsBeginImageContextWithOptions(self.xlView.bounds.size, NO, 0.0);

    

    //获取图形上下文路径

    CGContextRef ref = UIGraphicsGetCurrentContext();

    

    //通过layerrenderInContext 把内容渲染到图形上下文中

    [self.xlView.layer renderInContext:ref];

    

    //获取图片

    UIImage *getImage = UIGraphicsGetImageFromCurrentImageContext();

    

    //关闭图形上下文路径

    UIGraphicsEndImageContext();

    

    //保存相册

    UIImageWriteToSavedPhotosAlbum(getImage, self, @selector(image:didFinishSavingWithError:contextInfo:), @"nihao");

    

    //保存沙河

    //开始路径

    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    

    //保存文件路径

    NSString *filePath = [path stringByAppendingPathComponent:@"asd.png"];

    

    //保存 之前还要转换

    NSData *imageDate = UIImagePNGRepresentation(getImage);

    

    [imageDate writeToFile:filePath atomically:YES];

    


}



- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo

{

   NSString *str = @"保存成功";

    if (error)

    {

        str = @"保存失败";

    }else

    {

    str = @"保存成功";


    }

        

    NSLog(@"%@",str);

}








转载于:https://my.oschina.net/lufeidexin/blog/670624

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值