swift3.0對繪圖的API進行了優化,看起來更swift了。git
看下UI的構造。設置畫筆粗細、清空面板和保存到本地github
下面直接看畫板文件swift
這裏我作的比較複雜,記錄觸摸到的每一個點,再連成路徑,其實直接用可變路徑
CGMutablePath
可變路徑就能夠實現。數組
成員變量app
public var lineWidth:CGFloat = 1 fileprivate var allLineArray = [[CGPoint]]() //全部的線 記錄每一條線 fileprivate var currentPointArray = [CGPoint]() //當前畫線的點 畫完置空 增長到 線數組中 fileprivate var allPointWidth = [CGFloat]() //全部的線寬
設置觸摸時間,開始時記錄第一個點並重繪(不重繪就沒有隻畫一個點得效果),移動時不斷記錄並重繪。ide
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { let point:CGPoint = (event?.allTouches?.first?.location(in: self))! //路徑起點 currentPointArray.append(point) self.setNeedsDisplay() } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { let point:CGPoint = (event?.allTouches?.first?.location(in: self))! //路徑 currentPointArray.append(point) //刷新視圖 self.setNeedsDisplay() }
因爲咱們的點都是存在數組中,當要清空畫板時 只要將數組清空就能夠了優化
func cleanAll(){ allLineArray.removeAll() currentPointArray.removeAll() allPointWidth.removeAll() self.setNeedsDisplay() }
下面看下 重繪的主邏輯3d
override func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext() context?.setLineCap(.round) context?.setLineJoin(.round) //繪製以前的線 if allLineArray.count > 0 { //遍歷以前的線 for i in 0..<allLineArray.count { let tmpArr = allLineArray[i] if tmpArr.count > 0 { //畫線 context?.beginPath() //取出起始點 let sPoint:CGPoint = tmpArr[0] context?.move(to: sPoint) //取出全部當前線的點 for j in 0..<tmpArr.count { let endPoint:CGPoint = tmpArr[j] context?.addLine(to: endPoint) } context?.setLineWidth(allPointWidth[i]) context?.strokePath() } } } if currentPointArray.count > 0 { //繪製當前線 context?.beginPath() context?.setLineWidth(self.lineWidth) context?.move(to: currentPointArray[0]) print(currentPointArray[0]) for i in 0..<currentPointArray.count { context?.addLine(to: currentPointArray[i]) print(currentPointArray[i]) } context?.strokePath() } }
保存成圖片可很簡單,只要截屏設置範圍就行code
//保存圖片 @IBAction func savePic(_ sender: Any) { let height:CGFloat = self.view.bounds.size.height - self.saveBtn.frame.height - 10 let imageSize :CGSize = CGSize(width: self.view.bounds.size.width, height: height) UIGraphicsBeginImageContext(imageSize) view.layer.render(in: UIGraphicsGetCurrentContext()!) let img:UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() UIImageWriteToSavedPhotosAlbum(img, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil) } //保存圖片回調 func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafeRawPointer) { var resultTitle:String? var resultMessage:String? if error != nil { resultTitle = "錯誤" resultMessage = "保存失敗,請檢查是否容許使用相冊" } else { resultTitle = "提示" resultMessage = "保存成功" } let alert:UIAlertController = UIAlertController.init(title: resultTitle, message:resultMessage, preferredStyle: .alert) alert.addAction(UIAlertAction.init(title: "肯定", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) }
不過千萬別忘了給app設置相冊的權限blog
在info.plist中添加Privacy - Photo Library Usage Description
屬性便可,value值爲提示信息
效果:
有興趣的童靴可能夠直接用可變路徑實現下 邏輯更簡單 完了。
https://github.com/gongxiaokai/paintViewDemo