用storyBoard搭界面,最上面用到了一个toolBar ,中间用到了一个View,用来画东西,最下面在放一个View,用来存放三个按钮和一个UISlider
接下来就可以开始你的大作了,首先因为要在第二个拖的控件蓝色的View里画东西,所以要自定义一个类,
@property(nonatomic,strong)UIBezierPath *connectPath;
@end
@implementation LSdrawView
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
UIBezierPath *path = [UIBezierPath bezierPath];
self.connectPath = path;
[path moveToPoint:loc];
[self setNeedsDisplay];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
[self.connectPath addLineToPoint:loc];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
[self.connectPath stroke];
}
这段代码是第一步的到触摸的点然后,接线,在这里两个注意点,首先我们要接线创建一个UIBezierpath的路径去接收接线,第二我们要在DrawRect方法里进行渲染,第三个,你在View里想要显示线条就必须进行重绘,这是单线的做法
@interface LSdrawView()
@property(nonatomic,strong)UIBezierPath *connectPath;
@property(nonatomic,strong)NSMutableArray *connectArray;
@end
@implementation LSdrawView
-(NSMutableArray *)connectArray{
if (!_connectArray) {
_connectArray = [NSMutableArray array];
}
return _connectArray;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
UIBezierPath *path = [UIBezierPath bezierPath];
[self.connectArray addObject:path];
[path moveToPoint:loc];
[self setNeedsDisplay];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
[[self.connectArray lastObject] addLineToPoint:loc];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
for (UIBezierPath *path in self.connectArray) {
[path stroke];
}
}
这是多线处理,与多线的区别舍弃使用connectPath,新创建一个可变数组去存放画好的线,有几个注意点 首先数组里得先存放刚接触屏幕的首路径,然后在移动屏幕的时候使用可变数组中最后一个元素去添加添加新的线条,最后在渲染中使用for循环可变数组中的路径进行渲染
接下来设置线宽。。。
@interface ViewController ()
@property (weak, nonatomic) IBOutlet LSdrawView *myDrawView;
@property (weak, nonatomic) IBOutlet UISlider *mySlider;
@end
@implementation ViewController
- (IBAction)mySlider:(UISlider *)sender {
self.myDrawView.lineWidth = sender.value;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.myDrawView.lineWidth = self.mySlider.value;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
首先在控制器的.m文件中给Slider拖一根Action,我们要设置画板中的线宽,所以需要将故事板中的第二个View控件拖一根OutLet线,然后获取里面的线宽,可是线宽在View里是私有的,所以。。。下一步
#import <UIKit/UIKit.h>
@interface LSdrawView : UIView
@property(nonatomic,assign)CGFloat lineWidth;
@end
在自定义的类中设置一个线宽,因为.m中的属性是私有的获取到线宽之后,然后进行设置,注意要改slider的类型,按钮不能传id不然没有value转换的,接下来在View中改变线宽
@interface LSdrawView()
@property(nonatomic,strong)UIBezierPath *connectPath;
@property(nonatomic,strong)NSMutableArray *connectArray;
@end
@implementation LSdrawView
-(NSMutableArray *)connectArray{
if (!_connectArray) {
_connectArray = [NSMutableArray array];
}
return _connectArray;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth =self.lineWidth;//单独设置线宽
[self.connectArray addObject:path];
[path moveToPoint:loc];
[self setNeedsDisplay];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
[[self.connectArray lastObject] addLineToPoint:loc];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
for (UIBezierPath *path in self.connectArray) {
// path.lineWidth = self.lineWidth;//不能统一设置线宽,会出现一条线改变多条线改变
[path stroke];
}
}
在这里设置线宽,首先不能直接在drawRect方法里直接在for循环中设置线宽,会导致一变都变的情况,我们要在toughBegan方法中,单独设置线宽,接下来虽然实现了功能可使没有设置默认线宽,所以我们拖一根Slider属性线,然后在ViewDidLoad里设置默认线宽
设置颜色和线宽一个道理,给三个颜色的Button都拖到同一个点击事件,拿不到View中的颜色,所以在View的.h中声明颜色的成员属性,注意在View中设置颜色的时候,path没有自身的颜色属性,我们需要创建一个继承自UIBezierPath的类,然后设置里面的成员属性线的颜色,然后在path中重新设置线的颜色
@implementation LSdrawView
-(NSMutableArray *)connectArray{
if (!_connectArray) {
_connectArray = [NSMutableArray array];
}
return _connectArray;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
LSlineColor *path = [LSlineColor bezierPath];
path.lineColor = self.lineColor;
path.lineWidth =self.lineWidth;//单独设置线宽
[self.connectArray addObject:path];
[path moveToPoint:loc];
[self setNeedsDisplay];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
[[self.connectArray lastObject] addLineToPoint:loc];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
for (LSlineColor *path in self.connectArray) {
// path.lineWidth = self.lineWidth;//不能统一设置线宽,会出现一条线改变多条线改变
// [self.lineColor set];//不能统一设置颜色,会导致一变多变
[path.lineColor set];//设置线的颜色
[path stroke];
}
}
最后设置工具栏上的四个方法
- (IBAction)mySlider:(UISlider *)sender {
self.myDrawView.lineWidth = sender.value;
}
- (IBAction)colorButton:(UIButton *)sender {
self.myDrawView.lineColor = sender.backgroundColor;
}
- (IBAction)clearButton:(UIBarButtonItem *)sender {
[self.myDrawView.connectArray removeAllObjects];
[self.myDrawView setNeedsDisplay];
}
- (IBAction)backButton:(UIBarButtonItem *)sender {
[self.myDrawView.connectArray removeLastObject];
[self.myDrawView setNeedsDisplay];
}
- (IBAction)eraserButton:(UIBarButtonItem *)sender {
// LSlineColor *path = [LSlineColor bezierPath];
path.lineColor = self.myDrawView.backgroundColor;//这个方法不可以
// self.myDrawView.lineColor = self.myDrawView.backgroundColor;
// [self.myDrawView.connectArray addObject:path];
//还可以用下面的方法
self.myDrawView.lineColor = self.myDrawView.backgroundColor;
[self.myDrawView setNeedsDisplay];
}
- (IBAction)saveButton:(UIBarButtonItem *)sender {
UIGraphicsBeginImageContextWithOptions(self.myDrawView.frame.size, YES, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.myDrawView.layer renderInContext:ctx];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}