///controller
//
// ViewController.m
// PaintBoard
//
// Created by DukeMou on 15/4/22.
// Copyright (c) 2015 年 河南蓝鸥科技有限公司 . All rights reserved.
//
#import "RootViewController.h"
#import "PaintView.h"
@interface RootViewController ()
@property ( nonatomic , retain ) UITextField *textField; // 使用其自定义输入视图
- ( UIView *)_createFunctionPad; // 创建功能按钮的控制视图
@end
@implementation RootViewController
- ( void )dealloc {
[ _textField release ];
[ super dealloc ];
}
- ( UIView *)_createFunctionPad {
NSArray *titles = @[ @" 减细 " , @" 加粗 " , @" 撤销 " , @" 清空 " , @" 颜色 " ] ;
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake ( 0 , 0 , self . view . bounds . size . width , 80 )];
for ( int i = 0 ; i < titles. count ; i++) {
UIButton *button = [ UIButton buttonWithType : UIButtonTypeCustom ];
// 给按钮设置标题
[button setTitle :titles[i] forState : UIControlStateNormal ];
button. backgroundColor = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 0.8 ];
button. showsTouchWhenHighlighted = YES ;
[button addTarget : self action : @selector (handleButtonAction:) forControlEvents : UIControlEventTouchUpInside ];
// 设置 tag 值
button. tag = 100 + i;
// 设置 frame
CGFloat delta_x = (view. bounds . size . width - titles. count * 60 ) / (titles. count + 1 );
button. frame = CGRectMake ((delta_x + 60 ) * i + delta_x, 10 , 60 , 60 );
button. layer . cornerRadius = 30 ;
// 添加在 view 上显示
[view addSubview :button];
}
return [view autorelease ];
}
- ( UITextField *)textField {
if (! _textField ) {
self . textField = [[ UITextField alloc ] initWithFrame : CGRectZero ];
// 通过调用私有方法为 textField 添加输入视图
_textField . inputView = [ self _createFunctionPad ];
[ self . view addSubview : _textField ];
}
return _textField ;
}
- ( void )loadView {
PaintView *paintView = [[ PaintView alloc ] initWithFrame :[ UIScreen mainScreen ]. bounds ];
paintView. backgroundColor = [ UIColor whiteColor ];
self . view = paintView;
[paintView release ];
}
- ( void )viewDidLoad {
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
UIButton *menuButton = [ UIButton buttonWithType : UIButtonTypeSystem ];
menuButton. frame = CGRectMake ( self . view . bounds . size . width - 60 , 40 , 40 , 40 );
[menuButton setImage :[[ UIImage imageNamed : @" 屏幕快照 2015-09-19 11.44.30.png" ] imageWithRenderingMode : UIImageRenderingModeAlwaysOriginal ] forState : UIControlStateNormal ];
[menuButton setTitle : @" 菜单 " forState : UIControlStateNormal ];
[menuButton addTarget : self action : @selector (handleMenuButtonAction:) forControlEvents : UIControlEventTouchUpInside ];
[ self . view addSubview :menuButton];
}
- ( void )handleMenuButtonAction:( UIButton *)sender {
// 判断如果 textField 是第一响应者则撤销第一响应者权限,否则让其成为第一响应者
if ([ self . textField isFirstResponder ]) {
[ self . textField resignFirstResponder ];
} else {
[ self . textField becomeFirstResponder ];
}
}
- ( void )handleButtonAction:( UIButton *)sender {
PaintView *paintView = ( PaintView *) self . view ;
switch (sender. tag ) {
case 100 :
if (paintView. strokWidth > 4 ) {
paintView. strokWidth -= 2 ;
}
break ;
case 101 :
paintView. strokWidth += 2 ;
break ;
case 102 :
[paintView undoLastDrawing ];
break ;
case 103 :
[paintView cleanPaintBoard ];
break ;
case 104 :
sender. backgroundColor = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 0.8 ];
paintView. strokColor = sender. backgroundColor ;
break ;
default :
break ;
}
}
- ( void )didReceiveMemoryWarning {
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
// ViewController.m
// PaintBoard
//
// Created by DukeMou on 15/4/22.
// Copyright (c) 2015 年 河南蓝鸥科技有限公司 . All rights reserved.
//
#import "RootViewController.h"
#import "PaintView.h"
@interface RootViewController ()
@property ( nonatomic , retain ) UITextField *textField; // 使用其自定义输入视图
- ( UIView *)_createFunctionPad; // 创建功能按钮的控制视图
@end
@implementation RootViewController
- ( void )dealloc {
[ _textField release ];
[ super dealloc ];
}
- ( UIView *)_createFunctionPad {
NSArray *titles = @[ @" 减细 " , @" 加粗 " , @" 撤销 " , @" 清空 " , @" 颜色 " ] ;
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake ( 0 , 0 , self . view . bounds . size . width , 80 )];
for ( int i = 0 ; i < titles. count ; i++) {
UIButton *button = [ UIButton buttonWithType : UIButtonTypeCustom ];
// 给按钮设置标题
[button setTitle :titles[i] forState : UIControlStateNormal ];
button. backgroundColor = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 0.8 ];
button. showsTouchWhenHighlighted = YES ;
[button addTarget : self action : @selector (handleButtonAction:) forControlEvents : UIControlEventTouchUpInside ];
// 设置 tag 值
button. tag = 100 + i;
// 设置 frame
CGFloat delta_x = (view. bounds . size . width - titles. count * 60 ) / (titles. count + 1 );
button. frame = CGRectMake ((delta_x + 60 ) * i + delta_x, 10 , 60 , 60 );
button. layer . cornerRadius = 30 ;
// 添加在 view 上显示
[view addSubview :button];
}
return [view autorelease ];
}
- ( UITextField *)textField {
if (! _textField ) {
self . textField = [[ UITextField alloc ] initWithFrame : CGRectZero ];
// 通过调用私有方法为 textField 添加输入视图
_textField . inputView = [ self _createFunctionPad ];
[ self . view addSubview : _textField ];
}
return _textField ;
}
- ( void )loadView {
PaintView *paintView = [[ PaintView alloc ] initWithFrame :[ UIScreen mainScreen ]. bounds ];
paintView. backgroundColor = [ UIColor whiteColor ];
self . view = paintView;
[paintView release ];
}
- ( void )viewDidLoad {
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
UIButton *menuButton = [ UIButton buttonWithType : UIButtonTypeSystem ];
menuButton. frame = CGRectMake ( self . view . bounds . size . width - 60 , 40 , 40 , 40 );
[menuButton setImage :[[ UIImage imageNamed : @" 屏幕快照 2015-09-19 11.44.30.png" ] imageWithRenderingMode : UIImageRenderingModeAlwaysOriginal ] forState : UIControlStateNormal ];
[menuButton setTitle : @" 菜单 " forState : UIControlStateNormal ];
[menuButton addTarget : self action : @selector (handleMenuButtonAction:) forControlEvents : UIControlEventTouchUpInside ];
[ self . view addSubview :menuButton];
}
- ( void )handleMenuButtonAction:( UIButton *)sender {
// 判断如果 textField 是第一响应者则撤销第一响应者权限,否则让其成为第一响应者
if ([ self . textField isFirstResponder ]) {
[ self . textField resignFirstResponder ];
} else {
[ self . textField becomeFirstResponder ];
}
}
- ( void )handleButtonAction:( UIButton *)sender {
PaintView *paintView = ( PaintView *) self . view ;
switch (sender. tag ) {
case 100 :
if (paintView. strokWidth > 4 ) {
paintView. strokWidth -= 2 ;
}
break ;
case 101 :
paintView. strokWidth += 2 ;
break ;
case 102 :
[paintView undoLastDrawing ];
break ;
case 103 :
[paintView cleanPaintBoard ];
break ;
case 104 :
sender. backgroundColor = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 0.8 ];
paintView. strokColor = sender. backgroundColor ;
break ;
default :
break ;
}
}
- ( void )didReceiveMemoryWarning {
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
@end
//view
//.h
@interface
PaintView :
UIView
@property ( nonatomic , retain ) NSMutableArray *allLines; // 用于保存所有已经绘制的线条对象
@property ( nonatomic , retain ) UIColor *strokColor; // 画笔颜色
@property ( nonatomic , assign ) CGFloat strokWidth; // 画笔宽度
- ( void )undoLastDrawing; // 撤销上一次画线
- ( void )cleanPaintBoard; // 清空画板
@property ( nonatomic , retain ) NSMutableArray *allLines; // 用于保存所有已经绘制的线条对象
@property ( nonatomic , retain ) UIColor *strokColor; // 画笔颜色
@property ( nonatomic , assign ) CGFloat strokWidth; // 画笔宽度
- ( void )undoLastDrawing; // 撤销上一次画线
- ( void )cleanPaintBoard; // 清空画板
@end
//.m
//
// PaintView.m
// PaintBoard
//
// Created by DukeMou on 15/4/22.
// Copyright (c) 2015 年 河南蓝鸥科技有限公司 . All rights reserved.
//
#import "PaintView.h"
#import "Line.h"
@implementation PaintView
- ( void )dealloc {
[ _allLines release ];
[ _strokColor release ];
[ super dealloc ];
}
- ( NSMutableArray *)allLines {
if (! _allLines ) {
self . allLines = [ NSMutableArray array ];
}
return _allLines ;
}
- ( instancetype )initWithFrame:( CGRect )frame {
self = [ super initWithFrame :frame];
if ( self ) {
// 在初始化方法中设置默认的画笔颜色和画笔宽度
self . strokColor = [ UIColor blackColor ];
self . strokWidth = 2 ;
}
return self ;
}
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event {
UITouch *aTouch = [touches anyObject ];
// 获取线条的起始点
CGPoint startPoint = [aTouch locationInView : self . superview ];
// 创建一个贝塞尔曲线对象
UIBezierPath *path = [ UIBezierPath bezierPath ];
[path setLineCapStyle : kCGLineCapRound ];
[path setLineJoinStyle : kCGLineJoinRound ];
// 保存起始点
[path moveToPoint :startPoint];
// 创建数据模型对象,记录当前线条信息
Line *aLine = [ Line line ];
aLine. path = path;
aLine. color = self . strokColor ;
aLine. width = self . strokWidth ;
// 保存在数组中
[ self . allLines addObject :aLine];
}
- ( void )touchesMoved:( NSSet *)touches withEvent:( UIEvent *)event {
UITouch *aTouch = [touches anyObject ];
CGPoint currentPoint = [aTouch locationInView : self ];
// 获取当前的 Line 对象
Line *currentLine = self . allLines . lastObject ;
// 为当前的 Line 添加新的路径点
[currentLine. path addLineToPoint :currentPoint];
// 通知视图绘制当前界面
[ self setNeedsDisplay ];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- ( void )drawRect:( CGRect )rect {
// Drawing code
for ( Line *aLine in self . allLines ) {
[aLine. color setStroke ]; // 设置绘制用的画笔颜色
aLine. path . lineWidth = aLine. width ; // 设置线条宽度
[aLine. path stroke ]; // 根据路径信息绘制线条
}
}
- ( void )undoLastDrawing {
// 删除数组中最后一条线条对象
[ self . allLines removeLastObject ];
// 然后重绘界面
[ self setNeedsDisplay ];
}
- ( void )cleanPaintBoard {
[ self . allLines removeAllObjects ];
[ self setNeedsDisplay ];
}
// PaintView.m
// PaintBoard
//
// Created by DukeMou on 15/4/22.
// Copyright (c) 2015 年 河南蓝鸥科技有限公司 . All rights reserved.
//
#import "PaintView.h"
#import "Line.h"
@implementation PaintView
- ( void )dealloc {
[ _allLines release ];
[ _strokColor release ];
[ super dealloc ];
}
- ( NSMutableArray *)allLines {
if (! _allLines ) {
self . allLines = [ NSMutableArray array ];
}
return _allLines ;
}
- ( instancetype )initWithFrame:( CGRect )frame {
self = [ super initWithFrame :frame];
if ( self ) {
// 在初始化方法中设置默认的画笔颜色和画笔宽度
self . strokColor = [ UIColor blackColor ];
self . strokWidth = 2 ;
}
return self ;
}
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event {
UITouch *aTouch = [touches anyObject ];
// 获取线条的起始点
CGPoint startPoint = [aTouch locationInView : self . superview ];
// 创建一个贝塞尔曲线对象
UIBezierPath *path = [ UIBezierPath bezierPath ];
[path setLineCapStyle : kCGLineCapRound ];
[path setLineJoinStyle : kCGLineJoinRound ];
// 保存起始点
[path moveToPoint :startPoint];
// 创建数据模型对象,记录当前线条信息
Line *aLine = [ Line line ];
aLine. path = path;
aLine. color = self . strokColor ;
aLine. width = self . strokWidth ;
// 保存在数组中
[ self . allLines addObject :aLine];
}
- ( void )touchesMoved:( NSSet *)touches withEvent:( UIEvent *)event {
UITouch *aTouch = [touches anyObject ];
CGPoint currentPoint = [aTouch locationInView : self ];
// 获取当前的 Line 对象
Line *currentLine = self . allLines . lastObject ;
// 为当前的 Line 添加新的路径点
[currentLine. path addLineToPoint :currentPoint];
// 通知视图绘制当前界面
[ self setNeedsDisplay ];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- ( void )drawRect:( CGRect )rect {
// Drawing code
for ( Line *aLine in self . allLines ) {
[aLine. color setStroke ]; // 设置绘制用的画笔颜色
aLine. path . lineWidth = aLine. width ; // 设置线条宽度
[aLine. path stroke ]; // 根据路径信息绘制线条
}
}
- ( void )undoLastDrawing {
// 删除数组中最后一条线条对象
[ self . allLines removeLastObject ];
// 然后重绘界面
[ self setNeedsDisplay ];
}
- ( void )cleanPaintBoard {
[ self . allLines removeAllObjects ];
[ self setNeedsDisplay ];
}
@end
//model
//.h
#import
<Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Line : NSObject
@property ( nonatomic , retain ) UIBezierPath *path; // 记录线条路径
@property ( nonatomic , retain ) UIColor *color; // 线条颜色
@property ( nonatomic , assign ) CGFloat width; // 线条宽度
+ ( id )line; // 便利构造器方法
#import <UIKit/UIKit.h>
@interface Line : NSObject
@property ( nonatomic , retain ) UIBezierPath *path; // 记录线条路径
@property ( nonatomic , retain ) UIColor *color; // 线条颜色
@property ( nonatomic , assign ) CGFloat width; // 线条宽度
+ ( id )line; // 便利构造器方法
@end
//.m
#import
"Line.h"
@implementation Line
- ( void )dealloc {
[ _path release ];
[ _color release ];
[ super dealloc ];
}
+ ( id )line {
return [[[ Line alloc ] init ] autorelease ];
}
@implementation Line
- ( void )dealloc {
[ _path release ];
[ _color release ];
[ super dealloc ];
}
+ ( id )line {
return [[[ Line alloc ] init ] autorelease ];
}
@end