• swift3.0 CoreGraphics绘图-实现画板


    swift3.0对绘图的API进行了优化,看起来更swift了。

    看下UI的构造。设置画笔粗细、清空面板和保存到本地

    画板哦.gif

    下面直接看画板文件

    这里我做的比较复杂,记录触摸到的每个点,再连成路径,其实直接用可变路径CGMutablePath可变路径就可以实现。

    成员变量

        public var lineWidth:CGFloat = 1
        fileprivate var allLineArray = [[CGPoint]]()   //所有的线    记录每一条线
        fileprivate var currentPointArray = [CGPoint]() //当前画线的点  画完置空 增加到 线数组中
        fileprivate var allPointWidth = [CGFloat]()    //所有的线宽
    

    设置触摸时间,开始时记录第一个点并重绘(不重绘就没有只画一个点得效果),移动时不断记录并重绘。

        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()
        }
    

    下面看下 重绘的主逻辑

     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()  
            }
        }
    
    

    保存成图片可很简单,只要截屏设置范围就行

        //保存图片
        @IBAction func savePic(_ sender: Any) {
            
            let height:CGFloat = self.view.bounds.size.height - self.saveBtn.frame.height - 10
            let imageSize :CGSize = CGSize( 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设置相册的权限

    在info.plist中添加Privacy - Photo Library Usage Description属性即可,value值为提示信息

    相册权限.png

    效果:

    效果.png

    有兴趣的童靴可可以直接用可变路径实现下 逻辑更简单 完了。

    Demo地址

    https://github.com/gongxiaokai/paintViewDemo

  • 相关阅读:
    容易遗忘的配置
    linux中启动Zookeeper
    Linux中设置静态ip地址
    IDEA中工程上传到SVN
    Invalid bound statement(not found):cn.e3mall.mapper.TbItemMapper.selectByExample.....
    获取不到jdbc.driver的值解决办法
    idea中applicationContext-trans.xml中的Cannot resolve bean 'dataSource'...的问题解决
    idea中applicationContext-dao.xml文件中Cannot resolve file***** :spring xml model validation问题
    如何在IDEA中导入一个普通的java工程
    Navicate for mysql如何导入一个sql文件
  • 原文地址:https://www.cnblogs.com/gongxiaokai/p/7123816.html
Copyright © 2020-2023  润新知