【8.22|8.22 Draw 画图板】面向接口编程,多个类的共同点提出来,当做接口,充分利用多态的特性减少判断,利用封装,继承,能使得代码更加清晰易读,添加功能也不需要改太多东西。可扩展性高
将需要画的线,矩形,椭圆等都写成类
import UIKitclass ViewController: UIViewController {@IBAction func didClicked(sender: UIButton) {
let cv = self.view as! CustomView
//let array = cv.arraylet path = NSHomeDirectory() + "/Documents/1.jpg"
//
//NSKeyedArchiver.archiveRootObject(array, toFile: path)//1. 开始一个image上下文,绘制在内存的一个区域,保存为JPG
UIGraphicsBeginImageContext(self.view.bounds.size)
//2. 获取image context//a.
//let context = UIGraphicsGetCurrentContext()
//
//for line in array {
//line.draw(context!)
//}
//
//CGContextDrawPath(context, .Stroke)//b. 将视图上的所有内容绘制到当前的context中
//截屏
cv.drawViewHierarchyInRect(cv.bounds, afterScreenUpdates: true)//3. 从当前上下文中获取图片(UIImage)
let image = UIGraphicsGetImageFromCurrentImageContext()
//let data = https://www.it610.com/article/UIImagePNGRepresentation(image) //UIImage -> NSData
let data = https://www.it610.com/article/UIImageJPEGRepresentation(image, 0.4)
try! data?.writeToFile(path, options: .AtomicWrite)//4. 结束图形上下文
UIGraphicsEndImageContext()//1. 可以自动转换
//Int/Float... <-> NSNumber
//String <-> NSString
//2. 容器的转换有条件,元素必须能够自动转换
//Dictionary <-> NSDictionary
//Array <-> NSArray
//var strArray = Array()
//for point in array {
////CGPoint -> NSString
//strArray.append(NSStringFromCGPoint(point))
//}
////NSArray是一个不可变类型
//(strArray as NSArray).writeToFile(path, atomically: true)
}func changeShape(type: Shape.Type) {
let cv = self.view as! CustomView
cv.type = type
}//meta programming
//meta type: 元类型
@IBAction func didLineClicked(sender: UIButton) {
changeShape(Line.self)
}@IBAction func didRectClicked(sender: UIButton) {
changeShape(Rectangle.self)
}@IBAction func didCurveClicked(sender: UIButton) {
changeShape(Curve.self)
}@IBAction func didCircleClicked(sender: AnyObject) {
changeShape(Circle.self)
}
@IBAction func RedColor(sender: UIButton) {
let cv = self.view as! CustomView
cv.color = UIColor.redColor().self
}@IBAction func BlueColor(sender: UIButton) {
let cv = self.view as! CustomView
cv.color = UIColor.blueColor().self}
override func viewDidLoad() {
super.viewDidLoad()let cv = self.view as! CustomViewlet path = NSHomeDirectory() + "/Documents/array.plist"
let array = NSKeyedUnarchiver.unarchiveObjectWithFile(path)if let a = array as? Array {cv.array = a
}//let strArray = NSArray(contentsOfFile: path)!
//for str in strArray {
////NSString -> CGPoint
//let point = CGPointFromString(str as! String)
//cv.array.append(point)
//}
}override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKitclass CustomView: UIView {
var array = Array()
var type: Shape.Type = Line.self //默认为Line类型
var color: UIColor?
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
//1. 视图显示
//2. 大小、位置改变
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()for shape in array {CGContextSetLineWidth(context, 3)
CGContextSaveGState(context)CGContextSetStrokeColorWithColor(context,shape.color?.CGColor)
//多态
shape.draw(context!)CGContextStrokePath(context)
}CGContextDrawPath(context, .Stroke)
}func pointForTouches(touches: Set) -> CGPoint {let touch = touches.first! //UITouch
let point = touch.locationInView(self)return point
}override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//获取起点
let point = pointForTouches(touches)let shape = type.init() //必须有required的构造函数
if color != nil {
shape.color = color!
}
shape.addPoint(point)
array.append(shape)
}override func touchesMoved(touches: Set, withEvent event: UIEvent?) {
//获取动态点
let point = pointForTouches(touches)let shape = array.last
shape?.addPoint(point)self.setNeedsDisplay() //强制刷新(重绘)
}override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
//获取终点
let point = pointForTouches(touches)let shape = array.last
shape?.addPoint(point)self.setNeedsDisplay() //强制刷新(重绘)
}
}
import UIKit//enum ShapeType {
//case Line
//case Rect
//case Ellipse
//}//定义接口协议,方便其他类调用
protocol ShapeProtocol {
func draw(context: CGContextRef)
func addPoint(point: CGPoint)
}class Shape: NSObject, NSCoding, ShapeProtocol {//var begin: CGPoint!
//var end: CGPoint!
//var cgcolor: CGColor!//NSArray中只能存放对象
var points = Array()
var color:UIColor!
required override init() {
super.init()}required init?(coder aDecoder: NSCoder) {
//begin = aDecoder.decodeCGPointForKey("begin")
//end = aDecoder.decodeCGPointForKey("end")//取数据
if let array = aDecoder.decodeObjectForKey("points") as? Array {
points = array
}
if let m = aDecoder.decodeObjectForKey("color") as?UIColor{
color = m
}
}
//存数据
func encodeWithCoder(aCoder: NSCoder) {
//aCoder.encodeCGPoint(begin, forKey: "begin")
//aCoder.encodeCGPoint(end, forKey: "end")aCoder.encodeObject(points, forKey: "points")
aCoder.encodeObject(color, forKey: "color")}func draw(context: CGContextRef) {
}func addPoint(point: CGPoint) {
}
}
import UIKit
//两个点之间的画图,如线,矩形,定义为SimpleShape简单图形类,继承Shape图形类
class SimpleShape: Shape {
override func addPoint(point: CGPoint) {
let p = Point(point: point)if points.count < 2 {
points.append(p)
}
else {
points[1] = p
}
}
}
import UIKit
//线
class Line: SimpleShape{
override func draw(context: CGContextRef) {
//安全检查,如果少于两个点,就不画了
if points.count < 2 {
return
}CGContextMoveToPoint(context, points[0].x, points[0].y)
CGContextAddLineToPoint(context, points[1].x, points[1].y)
}
}
import UIKit
//矩形
class Rectangle: SimpleShape {
override func draw(context: CGContextRef) {
//安全检查,必须大于等于两个点才画
guard points.count >= 2 else {
return
}CGContextAddRect(context, CGRect(x: points[0].x, y: points[0].y, width: points[1].x - points[0].x, height: points[1].y - points[0].y))
}
}---------------------------```bash
import UIKit
任意线
class Curve: Shape {
override func addPoint(point: CGPoint) {
let p = Point(point: point)points.append(p)
}override func draw(context: CGContextRef) {
if points.count < 2 {
return
}CGContextMoveToPoint(context, points[0].x, points[0].y)
for p in points {
CGContextAddLineToPoint(context, p.x, p.y)
}
}
}
import UIKit
//椭圆
class Circle: SimpleShape {
override func draw(context: CGContextRef) {
let begin = points[0] //圆心
let end = points[1]//求半径
//r = ((x1-x0)**2 + (y1-y0)**2)^2
let radius = sqrt(pow((end.x - begin.x), 2) + pow((end.y - begin.y), 2))CGContextAddEllipseInRect(context, CGRect(x: begin.x - radius, y: begin.y - radius, width: radius + radius, height: radius + radius))
}
}
import UIKitclass Point: NSObject, NSCoding {
var x: CGFloat = 0
var y: CGFloat = 0init(point: CGPoint) {
super.init()x = point.x
y = point.y
}
//取数据
required init?(coder aDecoder: NSCoder) {
x = CGFloat(aDecoder.decodeDoubleForKey("x"))
y = CGFloat(aDecoder.decodeDoubleForKey("y"))
}
//存数据
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeDouble(Double(x), forKey: "x")
aCoder.encodeDouble(Double(y), forKey: "y")
}
}
编译运行结果如下:
文章图片
Paste_Image.png 真彩色,类似取色工具 pod search colorpick
协议和扩展都要实现属性,实际上是计算属性 {set get}
为防止重构,写程序前要留后路