質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1942閲覧

お絵描きアプリを作成中なのですが上手く動きません

sgt.kowalski

総合スコア34

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/07/22 07:56

iPhoneでタッチでお絵描きが出来るアプリを、swiftで作成中です。
滑らかな線を引くために、以下の処理をしています。

タッチ座標①
↓中間点①
タッチ座標②
↓中間点②
タッチ座標③

タッチ座標間の中間点を計算し、中間点①と中間点②を、タッチ座標②をコントロールポイントとした QuadBezierPath で結びます。

最初の指の移動では、最初にタッチした座標(A)と移動した後の座標(B)しかないので、最初にタッチした座標と(A)(B)の中間点を直線で結びます。
最後の指の移動についても同様で、最後の中間点と最終的に指を離した座標を直線で結びます。

###発生している問題・エラーメッセージ
エラーは出ていないのですが、最初のタッチで画面左上の座標(0,0)からタッチしたポイントまでいきなり線が引かれてしまいます。
また、指を離して、次にタッチすると、その2点間にも線が引かれてしまいます。

###該当のソースコード
swift3.0で書いてます。

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView! var lastPoint = CGPoint.zero var currentPoint = CGPoint.zero var midPoint1 = CGPoint.zero var midPoint2 = CGPoint.zero var swiped = false override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } //直線の描画 func drawLines(fromPoint:CGPoint,toPoint:CGPoint){ UIGraphicsBeginImageContext(self.view.frame.size) imageView.image?.draw(in: CGRect(x:0,y:0,width:self.view.frame.width,height:self.view.frame.height)) let context = UIGraphicsGetCurrentContext() context?.move(to:CGPoint(x:fromPoint.x,y:fromPoint.y)) context?.addLine(to:CGPoint(x:toPoint.x,y:toPoint.y)) context?.setBlendMode(CGBlendMode.normal) context?.setLineCap(CGLineCap.round) context?.setLineWidth(1) context?.setStrokeColor(UIColor(red:0,green:0,blue:0,alpha:1).cgColor) context?.strokePath() imageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } //曲線の描画 func drawCurves(fromPoint:CGPoint,toPoint:CGPoint,controlPoint:CGPoint){ UIGraphicsBeginImageContext(self.view.frame.size) imageView.image?.draw(in: CGRect(x:0,y:0,width:self.view.frame.width,height:self.view.frame.height)) let context = UIGraphicsGetCurrentContext() context?.move(to:CGPoint(x:fromPoint.x,y:fromPoint.y)) context?.addQuadCurve(to:CGPoint(x:toPoint.x,y:toPoint.y),control:CGPoint(x:controlPoint.x,y:controlPoint.y)) context?.setBlendMode(CGBlendMode.normal) context?.setLineCap(CGLineCap.round) context?.setLineWidth(5) context?.setStrokeColor(UIColor(red:0,green:0,blue:0,alpha:1).cgColor) context?.strokePath() imageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } //タッチスタート override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first{ lastPoint = touch.location(in: self.view) } } //タッチ移動 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first{ //初回の移動なら最初の中間点まで直線を引く if swiped == false{ let currentPoint = touch.location(in: self.view) let midPoint1 = CGPoint(x:(lastPoint.x + currentPoint.x)/2,y:(lastPoint.y + currentPoint.y)/2) drawLines(fromPoint:lastPoint,toPoint:midPoint1) lastPoint = currentPoint swiped = true }else{ //2回目以降の移動なら中間点を繋いで曲線を引く let currentPoint = touch.location(in: self.view) let midPoint2 = CGPoint(x:(lastPoint.x + currentPoint.x)/2,y:(lastPoint.y + currentPoint.y)/2) drawCurves(fromPoint:midPoint1,toPoint:midPoint2,controlPoint:lastPoint) midPoint1 = midPoint2 lastPoint = currentPoint swiped = true } } } //最後のタッチは、最後の中間点から最終点まで直線を引く override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first{ let currentPoint = touch.location(in: self.view) drawLines(fromPoint: midPoint1, toPoint: currentPoint) swiped = false } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. }

}

なにぶん初心者なもので、質問の書き方すらよく分かっていないのですが、上記コードのどこに問題があるのか、教えて頂けると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました!

下記3つの処理の中で、

//初回の移動なら最初の中間点まで直線を引く
//2回目以降の移動なら中間点を繋いで曲線を引く
//最後のタッチは、最後の中間点から最終点まで直線を引く

いちいち let で lastPoint や midPoint の変数を定義してたのですが、let を外すと、次の処理まで値が持ち越されるようになり、解決しました!

ということで、以下の理解で合ってるのでしょうか??

let で定義すると、その変数の値は、その関数の中でのみ保持されて、次の関数に持ち越されない。
let をつけずに代入すると、変数の値が次の関数まで持ち越される。

投稿2017/07/23 03:11

sgt.kowalski

総合スコア34

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問