うるおいらんど
アイキャッチ画像

【Swift】簡易ペイントを作成してみた。

追記があります。

とりあえず絵が描けるようになったので、コードをメモしておきます。結構時間かかってしまいました。

 

キャンバスを作成する

まずは絵を描くキャンバスを作成します。

var canvas = UIImageView()
canvas.frame = CGRect(x:0,y:0,width:screenWidth,height:screenHeight)
canvas.backgroundColor = UIColor.clearColor()
view.addSubview(canvas)

このUIImageViewの上に絵を描いていきます。

 

タッチイベントを作成する

画面がタッチされたときのアクションをかいていきます。

まずは指が触れたときに呼び出されるメソッドから。

 var bezierPath:UIBezierPath!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touchEvent = touches.first!
        let currentPoint:CGPoint = touchEvent.locationInView(canvas)
        bezierPath = UIBezierPath()
        bezierPath.lineWidth = 4.0
        bezierPath.moveToPoint(currentPoint)
}

Swift2.0ではtouchesがSetになっています。

3行目でタッチ時のイベントを取得します。

4行目で現在の座標を取得します。

bezierPathは曲線を扱うためのやつなんだとか。

線の太さを設定して、始点を現在の位置に設定しています。

 

次にドラッグ中のイベントです

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if bezierPath == nil {
            return
        }
        let touchEvent = touches.first!
        let currentPoint:CGPoint = touchEvent.locationInView(canvas)
        bezierPath.addLineToPoint(currentPoint)
        drawLine(bezierPath)
}

 

最初にもしもタッチ開始時にパスを初期化していない場合は処理を終了します。

そのあと現在の座標を取得して、線を引いていきます。 drawLineメソッドは後述します。

 

そして指を離したときのイベントです。

let lastDrawImage:UIImage!
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if bezierPath == nil {
            return
        }
        let touchEvent = touches.first!
        let currentPoint:CGPoint = touchEvent.locationInView(canvas)
        bezierPath.addLineToPoint(currentPoint)
        drawLine(bezierPath)
        lastDrawImage = canvas.image
}

途中までは先ほどと同じです。

最後にlastDrawImageにこれまで描いた絵を保存します。

これまで描いた絵を保存しておかないと黒い点がついてくるというよくわからないアプリに・・・

 

最後に描画時の処理です。

func drawLine(path:UIBezierPath){
        UIGraphicsBeginImageContext(canvas.frame.size)
        if lastDrawImage != nil {
            lastDrawImage.drawAtPoint(CGPointZero)
        }
        let lineColor = UIColor.blackColor()
        lineColor.setStroke()
        path.stroke()
        self.canvas.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
}

 

まずUIGraphicsBeginImageContextで非表示の描画領域を生成します。ここに描画してから画面に表示させます。

これまでに描いた絵があれば描画します。

線の色を決めて、線を描きます。

そしてUIImageViewのcanvasに画像を写します。

最後に描画を終了する文をかいて終わりです。

 

ひっかかったところ

タッチした座標を取得するときに、let touch = touches.anyObject() as UITouchとかいてもエラーが出るし、let touch = UITouch()とかいても取得できない。後者は当たり前なんですけども。。。

touchesはanyObjectじゃないよーということですね。バージョンの違いでエラーが出てしまいました。

touches.first!で座標を取得することができました。

ここまでたどり着くのにそこそこかかってしまった・・・

 

ちなみに.lineCapStyle = kCGLineCapRoundでエラーが出る原因もわからずとりあえず放置しています。バージョンが違うのかと思いきやそうでもなさそう。原因不明です。

 

あくまでも簡易・・・

undoボタンやredoボタンもなしで削除もできないという状態です。なのでただ線が描ける!というだけです。

これから様々な機能をつけていこうと思います。

今回は全体コードは割愛させていただきます。

   

参考リンク

Additional Notes追記

Swift4に対応してみました。

単純に置き換えただけですが。

アデュー

Comments

コメントはありません。

現在コメントフォームは工事中です。