Blog スタッフブログ

iOS Swift システム開発 ひとくちコードスニペット

[Swift]手書き対応UIViewサブクラスのコードスニペット

Swift

こんにちは、株式会社MIXシステム開発担当のBloomです。

今回はSwiftで利用できる手書き対応UIViewサブクラスのコードスニペットを紹介します。

class HandwritingView: UIView {

    private var lines: [[CGPoint]] = []

    // 描画パスを保存しておきたいとき
    var drawnLines: [[CGPoint]] {
        get { return lines }
        set {
            lines = newValue
            setNeedsDisplay()
        }
    }
    // ペン色設定
    var strokeColor: UIColor = .black
    // 太さ設定
    var lineWidth: CGFloat = 1.0

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.isMultipleTouchEnabled = false
        self.backgroundColor = .clear
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.isMultipleTouchEnabled = false
        self.backgroundColor = .clear
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        lines.append([])
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let point = touch.location(in: self)

        guard var lastLine = lines.popLast() else { return }
        lastLine.append(point)
        lines.append(lastLine)

        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }

        context.setStrokeColor(strokeColor.cgColor)
        context.setLineWidth(lineWidth)
        context.setLineCap(.round)

        for line in lines {
            guard let firstPoint = line.first else { continue }
            context.beginPath()
            context.move(to: firstPoint)
            for point in line.dropFirst() {
                context.addLine(to: point)
            }
            context.strokePath()
        }
    }
    // 描画クリア
    func clear() {
        lines.removeAll()
        setNeedsDisplay()
    }
}

これだけで手書きメモ機能を簡単に実装することができます。画像書き出し機能が欲しい場合はさらに下記関数を追加します。

func getImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(bounds: bounds)
    return renderer.image { context in
        self.layer.render(in: context.cgContext)
    }
}

これで手書きメモを実装することができました。良かったですね。