面向接口編程勺卢,多個類的共同點(diǎn)提出來伙判,當(dāng)做接口,充分利用多態(tài)的特性減少判斷值漫,利用封裝澳腹,繼承织盼,能使得代碼更加清晰易讀,添加功能也不需要改太多東西酱塔×ち冢可擴(kuò)展性高
將需要畫的線,矩形羊娃,橢圓等都寫成類
import UIKit
class ViewController: UIViewController {
@IBAction func didClicked(sender: UIButton) {
let cv = self.view as! CustomView
// let array = cv.array
let path = NSHomeDirectory() + "/Documents/1.jpg"
//
// NSKeyedArchiver.archiveRootObject(array, toFile: path)
//1. 開始一個image上下文唐全,繪制在內(nèi)存的一個區(qū)域,保存為JPG
UIGraphicsBeginImageContext(self.view.bounds.size)
//2. 獲取image context
//a.
// let context = UIGraphicsGetCurrentContext()
//
// for line in array {
// line.draw(context!)
// }
//
// CGContextDrawPath(context, .Stroke)
//b. 將視圖上的所有內(nèi)容繪制到當(dāng)前的context中
//截屏
cv.drawViewHierarchyInRect(cv.bounds, afterScreenUpdates: true)
//3. 從當(dāng)前上下文中獲取圖片(UIImage)
let image = UIGraphicsGetImageFromCurrentImageContext()
// let data = UIImagePNGRepresentation(image) //UIImage -> NSData
let data = UIImageJPEGRepresentation(image, 0.4)
try! data?.writeToFile(path, options: .AtomicWrite)
//4. 結(jié)束圖形上下文
UIGraphicsEndImageContext()
//1. 可以自動轉(zhuǎn)換
//Int/Float... <-> NSNumber
//String <-> NSString
//2. 容器的轉(zhuǎn)換有條件蕊玷,元素必須能夠自動轉(zhuǎn)換
//Dictionary <-> NSDictionary
//Array <-> NSArray
// var strArray = Array<String>()
// 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! CustomView
let path = NSHomeDirectory() + "/Documents/array.plist"
let array = NSKeyedUnarchiver.unarchiveObjectWithFile(path)
if let a = array as? Array<Line> {
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 UIKit
class CustomView: UIView {
var array = Array<Shape>()
var type: Shape.Type = Line.self //默認(rèn)為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)
//多態(tài)
shape.draw(context!)
CGContextStrokePath(context)
}
CGContextDrawPath(context, .Stroke)
}
func pointForTouches(touches: Set<UITouch>) -> CGPoint {
let touch = touches.first! //UITouch
let point = touch.locationInView(self)
return point
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//獲取起點(diǎn)
let point = pointForTouches(touches)
let shape = type.init() //必須有required的構(gòu)造函數(shù)
if color != nil {
shape.color = color!
}
shape.addPoint(point)
array.append(shape)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
//獲取動態(tài)點(diǎn)
let point = pointForTouches(touches)
let shape = array.last
shape?.addPoint(point)
self.setNeedsDisplay() //強(qiáng)制刷新(重繪)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
//獲取終點(diǎn)
let point = pointForTouches(touches)
let shape = array.last
shape?.addPoint(point)
self.setNeedsDisplay() //強(qiáng)制刷新(重繪)
}
}
import UIKit
//enum ShapeType {
// case Line
// case Rect
// case Ellipse
//}
//定義接口協(xié)議,方便其他類調(diào)用
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<Point>()
var color:UIColor!
required override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
// begin = aDecoder.decodeCGPointForKey("begin")
// end = aDecoder.decodeCGPointForKey("end")
// 取數(shù)據(jù)
if let array = aDecoder.decodeObjectForKey("points") as? Array<Point> {
points = array
}
if let m = aDecoder.decodeObjectForKey("color") as? UIColor{
color = m
}
}
// 存數(shù)據(jù)
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
//兩個點(diǎn)之間的畫圖垃帅,如線延届,矩形,定義為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) {
// 安全檢查方庭,如果少于兩個點(diǎn),就不畫了
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) {
// 安全檢查酱固,必須大于等于兩個點(diǎn)才畫
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 UIKit
class Point: NSObject, NSCoding {
var x: CGFloat = 0
var y: CGFloat = 0
init(point: CGPoint) {
super.init()
x = point.x
y = point.y
}
// 取數(shù)據(jù)
required init?(coder aDecoder: NSCoder) {
x = CGFloat(aDecoder.decodeDoubleForKey("x"))
y = CGFloat(aDecoder.decodeDoubleForKey("y"))
}
// 存數(shù)據(jù)
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeDouble(Double(x), forKey: "x")
aCoder.encodeDouble(Double(y), forKey: "y")
}
}
編譯運(yùn)行結(jié)果如下:
Paste_Image.png
真彩色械念,類似取色工具 pod search colorpick
協(xié)議和擴(kuò)展都要實(shí)現(xiàn)屬性,實(shí)際上是計算屬性 {set get}
為防止重構(gòu)运悲,寫程序前要留后路