画板
来源:互联网 发布:淘宝店卖什么好? 编辑:程序博客网 时间:2024/04/29 04:15
1.把一条条路径当成model,有线宽,颜色,存进数组,画到视图上,
PathModel.h
// line --- model
//颜色\路径\宽度
@interface PathModel :NSObject
@property (nonatomic,assign) CGMutablePathRef path;
@property (nonatomic,strong) UIColor *color;
@property (nonatomic,assign) CGFloat width;
- (void)dealloc
{
//释放路径
CGPathRelease(_path);
}
- (void)setPath:(CGMutablePathRef)path
{
if (_path != path) {
CGPathRelease(_path);
_path = (CGMutablePathRef)CGPathRetain(path);
}
}
2.自定义Button(UIControl 画)
ToolButton.h
#import <UIKit/UIKit.h>
//定义button的类型
typedefenum : NSUInteger{
kToolButtonTitleType,
kToolButtonColorType,
kToolButtonWidthType,
kToolButtonNoneType
} kToolButtonType;
@interface ToolButton :UIControl
//是否选中
@property (nonatomic,assign) BOOL checked;
@property (nonatomic,copy) NSString *title;
@property (nonatomic,strong) UIColor *color;
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) kToolButtonType type;
@end
#import "ToolButton.h"
@implementation ToolButton
- (void)drawRect:(CGRect)rect {
CGContextRef context =UIGraphicsGetCurrentContext();
if (self.type ==kToolButtonTitleType || self.type ==kToolButtonWidthType) {
//绘制标题
NSMutableParagraphStyle *style = [[NSMutableParagraphStyledefaultParagraphStyle]mutableCopy];
style.alignment =NSTextAlignmentCenter;
NSDictionary *attr = @{
NSFontAttributeName: [UIFontboldSystemFontOfSize:20],
NSParagraphStyleAttributeName : style
};
[self.titledrawInRect:rect withAttributes:attr];
} elseif (self.type ==kToolButtonColorType) {
//画内切圆
CGContextAddEllipseInRect(context, rect);
//CGContextSetFillColorWithColor(context, self.color.CGColor);
[self.colorsetFill];
CGContextDrawPath(context,kCGPathFill);
}
//绘制选中效果
if (self.checked) {
[[UIColorblackColor] set];
UIRectFrame(rect);
}
}
- (void)setChecked:(BOOL)checked
{
_checked = checked;
[selfsetNeedsDisplay];
}
@end
3.工具栏#import <UIKit/UIKit.h>
//block类型
typedefvoid(^ChangeColorBlock)(UIColor *);
typedefvoid(^ChangeWidthBlock)(CGFloat);
typedefvoid(^ChangeBlock)(void);
@class ToolButton;
@interface ToolView :UIView
{
UIView *_buttonView; //菜单栏
UIView *_colorView; //颜色
UIView *_widthView; //线宽
//声明block
ChangeColorBlock _colorBlock;
ChangeWidthBlock _widthBlock;
ChangeBlock _eraseBlock;
ChangeBlock _undoBlock;
ChangeBlock _clearBlock;
}
@property (nonatomic,strong) ToolButton *lastButton;
@property (nonatomic,strong) ToolButton *lastColor;
@property (nonatomic,strong) ToolButton *lastWidth;
@property (nonatomic,copy) ChangeColorBlock colorBlock;
@property (nonatomic,copy) ChangeWidthBlock widthBlock;
- (void)addErase:(ChangeBlock)eraseBlock undo:(ChangeBlock)undoBlock clear:(ChangeBlock)clearBlock;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [superinitWithFrame:frame];
if (self) {
[selfcreateMenuView];
[selfcreatColorView];
[selfcreateLineWidthView];
}
return self;
}
#pragma mark - 创建子视图
//菜单栏
- (void)createMenuView
{
//菜单栏的父视图
_buttonView = [[UIViewalloc] initWithFrame:CGRectMake(0,0, CGRectGetWidth(self.bounds),25)];
_buttonView.backgroundColor = [UIColorclearColor];
[selfaddSubview:_buttonView];
NSArray *titles =@[@"颜色",@"线宽",@"橡皮",@"撤销",@"清屏"];
CGFloat width = CGRectGetWidth(self.bounds) / titles.count;
//创建5个按钮
for (int i =0; i < titles.count; i++) {
ToolButton *button = [[ToolButtonalloc] initWithFrame:CGRectMake(i * width,0, width, 25)];
//指定button为title类型
button.type =kToolButtonTitleType;
button.title = titles[i];
button.backgroundColor = [UIColorclearColor];
button.tag =100 + i;
[buttonaddTarget:self
action:@selector(buttonAction:)
forControlEvents:UIControlEventTouchUpInside];
[_buttonViewaddSubview:button];
}
}
//颜色栏
- (void)creatColorView
{
_colorView = [[UIViewalloc] initWithFrame:CGRectMake(0,CGRectGetMaxY(_buttonView.frame),CGRectGetWidth(self.bounds),40)];
_colorView.backgroundColor = [UIColorclearColor];
_colorView.hidden =YES;
[selfaddSubview:_colorView];
NSArray *colors = @[
[UIColordarkGrayColor],
[UIColorredColor],
[UIColorgreenColor],
[UIColorblueColor],
[UIColoryellowColor],
[UIColororangeColor],
[UIColorpurpleColor],
[UIColorbrownColor],
[UIColorblackColor]
];
CGFloat width = CGRectGetWidth(self.bounds) / colors.count;
//创建按钮
for (int i =0; i < colors.count; i++) {
ToolButton *button = [[ToolButtonalloc] initWithFrame:CGRectMake(i * width,0, width, width)];
button.type =kToolButtonColorType;
button.color = colors[i];
button.backgroundColor = [UIColorclearColor];
[buttonaddTarget:self
action:@selector(tapColor:)
forControlEvents:UIControlEventTouchUpInside];
[_colorViewaddSubview:button];
}
}
//线宽栏
- (void)createLineWidthView
{
_widthView = [[UIViewalloc] initWithFrame:CGRectMake(0,CGRectGetMaxY(_buttonView.frame),CGRectGetWidth(self.bounds),40)];
_widthView.hidden =YES;
_widthView.backgroundColor = [UIColorclearColor];
[selfaddSubview:_widthView];
NSArray *widths =@[@1.0,@3.0,@5.0,@8.0,@10.0,@15.0,@20.0];
CGFloat width = CGRectGetWidth(self.bounds) / widths.count;
//创建按钮
for (int i =0; i < widths.count; i++) {
ToolButton *button = [[ToolButtonalloc] initWithFrame:CGRectMake(i * width,0, width, 25)];
button.type =kToolButtonWidthType;
button.title = [NSStringstringWithFormat:@"%@点", widths[i]];
button.width = [widths[i]floatValue];
button.backgroundColor = [UIColorclearColor];
[buttonaddTarget:self
action:@selector(tapWidth:)
forControlEvents:UIControlEventTouchUpInside];
[_widthViewaddSubview:button];
}
}
#pragma mark - Actions
- (void)buttonAction:(ToolButton *)sender
{
//1.把上一个button选中状态取消
self.lastButton.checked =NO;
//2.把点击的button设置为选中
sender.checked =YES;
//3.记录下选择的button
self.lastButton = sender;
//点击button,切换视图
switch (sender.tag -100) {
case 0:
_colorView.hidden =NO;
_widthView.hidden =YES;
break;
case 1:
_colorView.hidden =YES;
_widthView.hidden =NO;
break;
case 2: //橡皮
_eraseBlock();
break;
case 3: //撤销
_undoBlock();
break;
case 4: //清屏
_clearBlock();
break;
default:
break;
}
}
//颜色
- (void)tapColor:(ToolButton *)sender
{
//1.把上一个button选中状态取消
self.lastColor.checked =NO;
//2.把点击的button设置为选中
sender.checked =YES;
//3.记录下选择的button
self.lastColor = sender;
//block调用
if (_colorBlock !=nil) {
_colorBlock(sender.color);
}
}
//线宽
- (void)tapWidth:(ToolButton *)sender
{
//1.把上一个button选中状态取消
self.lastWidth.checked =NO;
//2.把点击的button设置为选中
sender.checked =YES;
//3.记录下选择的button
self.lastWidth = sender;
if (_widthBlock !=nil) {
_widthBlock(sender.width);
}
}
- (void)addErase:(ChangeBlock)eraseBlock undo:(ChangeBlock)undoBlock clear:(ChangeBlock)clearBlock
{
_eraseBlock = eraseBlock;
_undoBlock = undoBlock;
_clearBlock = clearBlock;
}
@end
4.绘画视图#import <UIKit/UIKit.h>
@interface PanelView :UIView
{
NSMutableArray *_pathes;
}
@property (nonatomic,assign) CGMutablePathRef currentPath;
@property (nonatomic,strong) UIColor *currentColor;
@property (nonatomic,assign) CGFloat currentWidth;
//清屏
- (void)clear;
//撤销
- (void)undo;
@end
@implementation PanelView
/*
* 绘制多条线:
* 1. 初始化就创建路径,一直使用同一条路径
* 2. 每创建一个路径,就保存在数组中
*/
- (instancetype)initWithFrame:(CGRect)frame
{
self = [superinitWithFrame:frame];
if (self) {
// _path = CGPathCreateMutable();
_pathes = [NSMutableArrayarray];
//设置默认的画笔
_currentColor = [UIColorblackColor];
_currentWidth =5;
}
return self;
}
- (void)drawRect:(CGRect)rect {
//上下文
CGContextRef context =UIGraphicsGetCurrentContext();
/*
//从数组中取出路径,绘制
for (id path in _pathes) {
CGMutablePathRef lastPath = (__bridge CGMutablePathRef)(path);
CGContextAddPath(context, lastPath);
//设置颜色和线宽
//[[UIColor redColor] set];
// CGContextSetRGBStrokeColor(context, 0, 0, 0, 1)
// CGContextSetLineWidth(context, <#CGFloat width#>)
CGContextDrawPath(context, kCGPathStroke);
}
*/
//遍历所有的路径,把路径绘制
for (PathModel *modelin _pathes) {
//路径添加到上下文
CGContextAddPath(context, model.path);
//设置上下文(颜色)
[model.colorset];
//(线宽)
CGContextSetLineWidth(context, model.width);
//绘制
CGContextDrawPath(context,kCGPathStroke);
}
//第一次绘制的路径如果为空,就不绘制
if (_currentPath !=nil) {
//路径添加到上下文
CGContextAddPath(context, _currentPath);
//设置上下文
CGContextSetLineWidth(context,_currentWidth);
[_currentColorset];
//绘制
CGContextDrawPath(context,kCGPathStroke);
/*
PathModel *model = [_pathes objectAtIndex:0];
CGContextAddPath(context, model.path);
[model.color set];
CGContextSetLineWidth(context, model.width);
*/
}
}
//触摸开始
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
//创建路径
_currentPath =CGPathCreateMutable();
//设置起始点
CGPathMoveToPoint(_currentPath,NULL, location.x, location.y);
}
//触摸移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
//移动,路径上添加线
CGPathAddLineToPoint(_currentPath,NULL, location.x, location.y);
//手动调用drawRect:
[selfsetNeedsDisplay];
}
//触摸结束
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
/*
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
//路径上添加结束点
CGPathAddLineToPoint(_currentPath, NULL, location.x, location.y);
*/
//把路径保存注意桥接
//[_pathes addObject:(__bridge id)(_currentPath)];
// if (_pathes == nil) {
// _pathes = [NSMutableArray array];
// }
//创建model,保存绘图的属性
PathModel *model = [[PathModelalloc] init];
model.path = _currentPath;
model.color = _currentColor;
model.width = _currentWidth;
[_pathesaddObject:model];
//释放路径
CGPathRelease(_currentPath);_currentPath =nil;
}
#pragma mark - 图形界面方法
- (void)clear
{
[_pathesremoveAllObjects];
// _pathes = [NSMutableArray array];
// _pathes = nil;
//调用drawRect方法,重绘界面
[selfsetNeedsDisplay];
}
- (void)undo
{
[_pathesremoveLastObject];
[selfsetNeedsDisplay];
}
@end
#define kStatusBarHeight 20
#define kScreenWidth ([UIScreen mainScreen].bounds.size.width)
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
PanelView *panel = [[PanelViewalloc] initWithFrame:self.view.bounds];
panel.backgroundColor = [UIColorwhiteColor];
[self.viewaddSubview:panel];
ToolView *tool = [[ToolViewalloc] initWithFrame:CGRectMake(0,kStatusBarHeight, kScreenWidth, 100)];
tool.backgroundColor = [UIColorgrayColor];
[self.viewaddSubview:tool];
//block赋值,设置block来修改相应的属性
tool.colorBlock = ^(UIColor *color){
panel.currentColor = color;
};
tool.widthBlock = ^(CGFloat width){
panel.currentWidth = width;
};
[tooladdErase:^{
panel.currentColor = [UIColorwhiteColor];
panel.currentWidth =20;
}undo:^{
[panelundo];
}clear:^{
[panelclear];
}];
}
效果图- 画板
- 画板
- 画板
- 画板
- 做画板
- JS画板
- WP7 ,画板
- ios 画板
- 简易画板
- 涂鸦画板
- 画板案例
- Android画板
- Bitmap画板
- 画板记录
- 画板 ios
- 画板项目
- 练习:画板
- 【JAVA】 画板
- 对Hash Join的一次优化
- 算法导论 python代码 第六章
- PHP Fatal error: Cannot redeclare class
- C++重载(overload)、重写(overwrite,也称隐藏)、覆盖(override)
- MySQL数据类型的使用总结
- 画板
- 第三章第七题
- 在Windows上安装msysgit(Git for Windows)
- 【翻译自mos文章】SYSAUX表空间里边存放的内容
- 解决QT多线程中undefined reference to 'pthread_create'的错误
- JS判断客户端是否是iOS或者Android
- POJ2506 Tiling 【大数和】
- 第三章第八题
- Js repalce_all