在Swift中绘制像记号笔或笔尖

时间:2016-12-04 20:14:28

标签: ios swift drawing core-graphics

我有一个关于在swift中绘图的问题...我可以使用context.move和context.addLine和context.stroke等创建一个使用CGContext的简单绘图应用程序... 我甚至使用bezierPath使其平滑...我的工作但是当你快速绘制它时,有时候会发生故障......但是Instagram的故事部分中的绘图应用程序......它像天然画笔或记号笔一样绘制......带有角度的标记提示......我的应用程序中的那些故障不会出现在那个Instagram绘图应用程序中 尽管我能理解他们使用3d触摸力来增加笔尖宽度+刷尖像解决方案

任何人都可以请我指教程或主题,在那里我可以学习如何实现这一目标......如果你能指出相关的api / class和方法,我可以自己学习......

下面是2个截图,显示了我的绘图应用程序和Instagram的故事绘图

我的应用程序与Instagram的故事:

这是我的代码......

import UIKit

struct Line {

    var points:[CGPoint]
    var color:UIColor?
    var opacity:CGFloat?
    var size:CGFloat?

    init() {
        self.points = []
    }

}

class DrawingVC: UIViewController {

    // Variables

    var swiped:Bool = false
    var line:Line = Line()
    var lines:[Line] = []
    var lastPoint:CGPoint? = nil
    var orginalImage:UIImage?

    var colorPink = UIColor.rgb(r: 229, g: 23, b: 125)
    var colorOrange = UIColor.rgb(r: 255, g: 139, b: 0)
    var colorYellow = UIColor.rgb(r: 255, g: 230, b: 0)
    var colorGreen = UIColor.rgb(r: 107, g: 222, b: 0)
    var colorBlue = UIColor.rgb(r: 12, g: 205, b: 229)


    var markerOpacity:CGFloat = 0.60
    var markerColor:UIColor = UIColor.rgb(r: 255, g: 139, b: 0)
    var markerSize:CGFloat = 24


    // Visual Elements

    let mainImageView:UIImageView = {
        let v = UIImageView()
        v.contentMode = .scaleAspectFit
        v.clipsToBounds = true
        return v
    }()

    let tempImageView:UIImageView = {
        let v = UIImageView()
        v.contentMode = .scaleAspectFit
        v.clipsToBounds = true
        return v
    }()


    override func viewDidLoad() {

        super.viewDidLoad()
        view.backgroundColor = UIColor.black

        setupViews()

        updateCurrentStep()
        updateTotalDrawing()

    }



    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        swiped = false
        guard let point = touches.first?.location(in: self.view) else {
            return
        }

        lastPoint = point

        line = Line()
        line.color = markerColor
        line.opacity = markerOpacity
        line.size = markerSize
        line.points.append(point)

        updateCurrentStep()

    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        swiped = true

        if #available(iOS 9.0, *) {

            guard let point = touches.first, let coalescedTouches = event?.coalescedTouches(for: point) else {
                return
            }
            coalescedTouches.forEach {

                lastPoint = $0.location(in: self.view)
                line.points.append($0.location(in: self.view))

            }

        } else {

            guard let point = touches.first?.location(in: self.view) else {
                return
            }

            lastPoint = point
            line.points.append(point)

        }

        updateCurrentStep()

    }



    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        if !swiped {
            line.points.append(lastPoint!)
        }

        lines.append(line)

        clearTempImage()
        updateTotalDrawing()


    }

    func drawLine(_ line:Line, context: CGContext) {

        let bezierPath = UIBezierPath()
        bezierPath.lineCapStyle = .square
        bezierPath.lineJoinStyle = .miter
        bezierPath.miterLimit = 24
        bezierPath.lineWidth = line.size!
        bezierPath.interpolatePointsWithHermite(interpolationPoints: line.points)
        line.color!.withAlphaComponent(line.opacity!).setStroke()
        bezierPath.stroke()

    }


    func clearTempImage() {

        tempImageView.image = UIImage()

    }

    func updateCurrentStep() {

        UIGraphicsBeginImageContext(view.frame.size)
        guard let context = UIGraphicsGetCurrentContext() else { return }

        if line.points.count > 1 {
            drawLine(line, context: context)
        }

        tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

    }

    func updateTotalDrawing() {

        UIGraphicsBeginImageContext(view.frame.size)
        guard let context = UIGraphicsGetCurrentContext() else { return }

        if let oImage = self.orginalImage {

            let iw = oImage.size.width
            let ih = oImage.size.height
            let cw = self.view.bounds.size.width
            let ch = self.view.bounds.size.height

            let ir = iw/ih
            let cr = cw/ch

            let newImageWidth:CGFloat
            let newImageHeight:CGFloat


            if( cr < ir ) {
                newImageWidth = cw
                newImageHeight = ch*ir
            } else {
                newImageWidth = cw*ir
                newImageHeight = ch
            }

            print( newImageWidth, newImageHeight )

            let yPos = (self.view.bounds.size.height - newImageHeight) / 2
            let finalRect = CGRect.init(x: 0, y: yPos, width: newImageWidth, height: newImageHeight)
            self.orginalImage?.draw(in: finalRect, blendMode: .normal, alpha: 1)

        }



        for line in lines {
            drawLine(line, context: context)
        }

        mainImageView.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

    }

    func setupViews() {


        view.addSubview(mainImageView)
        view.addSubview(tempImageView)

        view.addConstraintsWithFormat(format: "H:|[v0]|", views: mainImageView)
        view.addConstraintsWithFormat(format: "V:|[v0]|", views: mainImageView)

        view.addConstraintsWithFormat(format: "H:|[v0]|", views: tempImageView)
        view.addConstraintsWithFormat(format: "V:|[v0]|", views: tempImageView)


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override var prefersStatusBarHidden: Bool {
        return true
    }

你也可以使用Instagram故事画画你的东西......你会理解我在你使用它时的意思......

0 个答案:

没有答案
相关问题