MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

タッチで画像を動かす (UIImage View, UITouch, swift 1.2)

画像 (UIImage View) をタッチ操作で動かしたくなりました。

生まれて初めてgithubにXcode Projectを上げました。

GitHub - anthrgrnwrld/image_control

自分ポイント1

  • 画像表示用IBOutletを作成。
    @IBOutlet var imageBeHereNow: UIImageView!

自分ポイント2

  • タッチし始めた時、touchesBegan というメソッドが呼ばれる。
  • ここでスタート位置の座標(画像位置とタッチ位置の二つ)を取得する。
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        //println("\(__FUNCTION__) is called!!")
        
        // タッチをやり始めた座標を取得
        let touch: UITouch = touches.first as! UITouch
        startPoint = touch.locationInView(self.view)
        //println("startPoint =\(startPoint)")
        
        // タッチをやり始めた時のイメージの座標を取得
        imageBeHereNowPoint = self.imageBeHereNow.frame.origin
        //println("imageBeHereNowPoint =\(imageBeHereNowPoint)")
    }

自分ポイント3

  • タッチして動かしている時、touchesMoved というメソッドが呼ばれる。
  • ここでその時点でタッチしている座標が取得できるので、スタート位置座標との差分から移動量を計算する。
  • 移動量からイメージを移動させる。
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        //println("\(__FUNCTION__) is called!!")
        
        // タッチ中の座標を取得
        let touch: UITouch = touches.first as! UITouch
        let location: CGPoint = touch.locationInView(self.view)
        //println("location =\(location)")
            
        // 移動量を計算
        let deltaX: CGFloat = CGFloat(location.x - startPoint!.x)
        let deltaY: CGFloat = CGFloat(location.y - startPoint!.y)
        //println("deltaX: \(deltaX), deltaY: \(deltaY)")
            
        // イメージを移動
        self.imageBeHereNow.frame.origin.x = imageBeHereNowPoint!.x + deltaX
        self.imageBeHereNow.frame.origin.y = imageBeHereNowPoint!.y + deltaY        
    }

自分ポイント4

  • スタート位置の座標(画像位置とタッチ位置の二つ)を保存するプロパティは、スコープを大きめで取った。なぜならtouchesMovedメソッド内でも、その値を使用したいから。
class ViewController: UIViewController {
    @IBOutlet var imageBeHereNow: UIImageView!
    var startPoint: CGPoint?
    var imageBeHereNowPoint: CGPoint?

    ...

    }

自分ポイント5

  • 画像を触ったか判別するフラグを作った。
    var isImageInside: Bool?
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        ...
        
        // イメージの範囲
        let MinX = imageBeHereNowPoint!.x
        let MaxX = imageBeHereNowPoint!.x + self.imageBeHereNow!.frame.width
        let MinY = imageBeHereNowPoint!.y
        let MaxY = imageBeHereNowPoint!.y + self.imageBeHereNow!.frame.height
        
        // イメージの範囲内をタッチした時のみisImageInsideをtrueにする
        if (MinX <= startPoint!.x && startPoint!.x <= MaxX) && (MinY <= startPoint!.y && startPoint!.y <= MaxY) {
            println("Inside of Image")
            isImageInside = true
            
        } else {
            println("Outside of Image")
            isImageInside = false
        }
    }
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        //println("\(__FUNCTION__) is called!!")
        
        if isImageInside! {
            // タッチ中の座標を取得
            let touch: UITouch = touches.first as! UITouch
            let location: CGPoint = touch.locationInView(self.view)
            //println("location =\(location)")
            
            // 移動量を計算
            let deltaX: CGFloat = CGFloat(location.x - startPoint!.x)
            let deltaY: CGFloat = CGFloat(location.y - startPoint!.y)
            //println("deltaX: \(deltaX), deltaY: \(deltaY)")
            
            // イメージを移動
            self.imageBeHereNow.frame.origin.x = imageBeHereNowPoint!.x + deltaX
            self.imageBeHereNow.frame.origin.y = imageBeHereNowPoint!.y + deltaY
        } else {
            // Do nothing
        }
        
    }

もっといい書き方があるであろうことは、薄々分かっています。 効率的な書き方がありましたら、どんどん教えて下さい。 お願いします。