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

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

ただいまの
回答率

90.76%

  • Swift

    6717questions

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

  • Xcode

    3857questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

タッチ→ドラッグ(移動)の処理を各ラベルに対して行いたい(switchや配列を用いて)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 83

TRON1216.

score 17

立ち位置のアプリを作ろうとしています。

  • やりたいこと
    計10個あるラベル(番号が書かれた丸)のうち、いずれかのラベルをタッチしてドラッグするとそのラベルが移動するという処理

  • やってみたこと
    各ラベルに.tagをつけて、switchで書いてみた

  • 問題点
    プログラムの実行はできるがラベルが全く(どれも)動かない

間違っているところやご指摘があれば是非教えていただきたいです。よろしくお願いいたします。
なお、コードに関しましては、投稿の文字数の関係からラベルの数を2つにし、タッチ→ドラッグ(移動)の処理の部分だけ載せています。

/*
ラベルを作る   
*/
for n in 0...1 {
            mylabel[n] = UILabel(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
            mylabel[n].text = "1"
            mylabel[n].textAlignment = NSTextAlignment.center //画面長い方の中心に来るように設定違うかも
            mylabel[n].layer.masksToBounds = true
            mylabel[n].center = self.view.center //画面の短い方の中心に来るように設定
            mylabel[n].layer.cornerRadius = 20.0


            switch n {
            case 0 :
                mylabel[0].backgroundColor = UIColor.red
                //mylabel[0].center = self.view.center
                mylabel[0].tag = 0 //消したいラベルをタグで指定するために必要*/
            case 1 :
                mylabel[1].backgroundColor = UIColor.blue
                 mylabel[1].tag = 1 //消したいラベルをタグで指定するために必要*/

            default:
                break
            }
            self.view.addSubview(mylabel[n])
        }
    /*
     タッチを感知した際に呼ばれるメソッド.
     */
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //print("touchesBegan")
        print("touchesBeganが呼ばれました")

        // Labelアニメーション.
        UIView.animate(withDuration: 0.06,
                       // アニメーション中の処理.
            animations: { () -> Void in
                func myFunc(sender: UILabel){
                    switch sender.tag{
                    case 0: self.mylabel[0].transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
                    case 1: self.mylabel[1].transform = CGAffineTransform(scaleX: 0.9, y: 0.9)

                    default:
                        break
                    }
                }

        })
        { (Bool) -> Void in
        }


    }

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

        print("touchesMovedが呼ばれました")

        // タッチイベントを取得.
        let aTouch: UITouch = touches.first!



        func myFunc(sender: UILabel){
            switch sender.tag{
            case 0:
                let location_0 = aTouch.location(in: mylabel[0]/*self.view*/)
                let prevLocation_0 = aTouch.previousLocation(in: mylabel[0]/*self.view*/)
                var myFrame_0: CGRect = mylabel[0]/*self.view*/.frame
                let deltaX_0: CGFloat = location_0.x - prevLocation_0.x
                let deltaY_0: CGFloat = location_0.y - prevLocation_0.y
                myFrame_0.origin.x += deltaX_0
                myFrame_0.origin.y += deltaY_0
                Finallocation1 = myFrame_0.origin.x
                Finallocation2 = myFrame_0.origin.y
                mylabel[0]/*self.view*/.frame = myFrame_0
            case 1:
                let location_1 = aTouch.location(in: mylabel[1]/*self.view*/)
                let prevLocation_1 = aTouch.previousLocation(in: mylabel[1]/*self.view*/)
                var myFrame_1: CGRect = mylabel[1]/*self.view*/.frame
                let deltaX_1: CGFloat = location_1.x - prevLocation_1.x
                let deltaY_1: CGFloat = location_1.y - prevLocation_1.y
                myFrame_1.origin.x += deltaX_1
                myFrame_1.origin.y += deltaY_1
                Finallocation1 = myFrame_1.origin.x
                Finallocation2 = myFrame_1.origin.y
                mylabel[1]/*self.view*/.frame = myFrame_1

            default:
                break
            }
        }
}

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

        print("touchesEndedが呼ばれました")

        // Labelアニメーション.
        UIView.animate(withDuration: 0.1,

                       // アニメーション中の処理.
            animations: { () -> Void in
                func myFunc(sender: UILabel){
                    switch sender.tag{
                    case 0:
                        self.mylabel[0].transform = CGAffineTransform(scaleX: 0.4, y: 0.4)
                        self.mylabel[0].transform = CGAffineTransform(scaleX: 1.0, y: 1.0)

                    case 1:
                        self.mylabel[1].transform = CGAffineTransform(scaleX: 0.4, y: 0.4)
                        self.mylabel[1].transform = CGAffineTransform(scaleX: 1.0, y: 1.0)



                    default:
                        break
                    }
                }


        })
        { (Bool) -> Void in

        }
}

override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



}

イメージ説明
イメージ説明
以下は、回答者様のご指摘により変更したことを書きました。書き方や各場所がまだ理解できておらず、まだ解決していない状態です。

labelT.isUserInteractionEnabled = true


if let labelT = touches.first?.view as? UILabel {
                    //labelに対してあんなことや、こんなことを‥
                }


を用いて各Touchesのメソッドの中身を変えました。

 /*
     タッチを感知した際に呼ばれるメソッド.
     */
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //print("touchesBegan")
        print("touchesBeganが呼ばれました")
        // Labelアニメーション.
        UIView.animate(withDuration: 0.06,
                       // アニメーション中の処理.
            animations: { () -> Void in
                if let labelT = touches.first?.view as? UILabel {
                    labelT.isUserInteractionEnabled = true
                    labelT.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
                    //labelに対してあんなことや、こんなことを‥
                }
        })
        { (Bool) -> Void in
        }       
    }

 /*
     ドラッグを感知した際に呼ばれるメソッド.
     (ドラッグ中何度も呼ばれる)
     */       
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        print("touchesMovedが呼ばれました")
        //label.isUserInteractionEnabled = true
        // タッチイベントを取得.
        let aTouch: UITouch = touches.first!

        // 移動した先の座標を取得.
        if let labelT = touches.first?.view as? UILabel {
            labelT.isUserInteractionEnabled = true
            let location = aTouch.location(in: labelT/*self.view*/)
            let prevLocation = aTouch.previousLocation(in: labelT/*self.view*/)
            var myFrame: CGRect = labelT/*self.view*/.frame
            let deltaX: CGFloat = location.x - prevLocation.x
            let deltaY: CGFloat = location.y - prevLocation.y
            myFrame.origin.x += deltaX
            myFrame.origin.y += deltaY
            Finallocation1 = myFrame.origin.x
            Finallocation2 = myFrame.origin.y
            labelT/*self.view*/.frame = myFrame
            //labelに対してあんなことや、こんなことを‥
        }
}

/*
     指が離れたことを感知した際に呼ばれるメソッド.
     */
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        print("touchesEndedが呼ばれました")
        //label.isUserInteractionEnabled = true
        // Labelアニメーション.
        UIView.animate(withDuration: 0.1,

                       // アニメーション中の処理.
            animations: { () -> Void in
                if let labelT = touches.first?.view as? UILabel {
                    labelT.isUserInteractionEnabled = true
                    labelT.transform = CGAffineTransform(scaleX: 0.4, y: 0.4)
                    labelT.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
                    //labelに対してあんなことや、こんなことを‥
                }
        })
        { (Bool) -> Void in          
        }    
        print("移動先の座標は、x=\(Finallocation1)、y=\(Finallocation2)です")

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2018/05/25 09:07

    ボタンが一つなら動かせるのでしょうか?

    キャンセル

  • TRON1216.

    2018/05/25 15:31

    このコード(ラベルを複数作り、switchで分岐)では一つも動かせません。しかし、ラベルを一個だけ作り、移動させるということはできました。

    キャンセル

回答 1

checkベストアンサー

0

とりあえず二点ほど。

 #1 UILabelはデフォルトではタッチ無効

label.isUserInteractionEnabled = true

を追加してください。(一つでは出来ているということですので書き忘れでしょうか?)

 #2 タッチしたUILabel

各touches*の中で func myFunc(sender: UILabel){ ~ } と書いていますが、これは関数を定義しているだけで実行されていません。

タッチしたUILabelを取得しようとしているのだと思いますが、タッチしたUILabelはUITouchから取れますので変な小細工は不要です。

if let label = touches.first?.view as? UILabel {
    //labelに対してあんなことや、こんなことを‥
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/26 23:14

    丁寧な回答大変嬉しく思います。やってみたのですが、うまくいきません。#1で指摘している文は各Touchesの中に書いたのですが合ってますでしょうか、、?#2も書いたのですが、うまくいかないので修正したコードを載せます。確認よろしくお願いいたします。

    キャンセル

  • 2018/05/27 00:09

    ちょっと考えてみて下さい。
    「タッチを有効にする処理」をタッチ処理の中に書いて意味があると思いますか?

    キャンセル

  • 2018/05/27 01:20

    確かに、、
    やってみます!

    キャンセル

  • 2018/05/27 01:33

    無事それぞれのラベルを動かすことができました!ありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    swift Button タップ スワイプ

    現在、タップとスワイプの二つを一つのボタンで行おうとしています。 ボタンをタップしたらUIViewを出して ボタンをスワイプしたらそのボタンが指に沿って移動する・・・

  • 解決済

    Swiftの座標取得ができないです...

    座礁取得をするコード(コピペなのですが) を記述してみたら Cannot call value of non-function type '((UIView?) -> CG

  • 解決済

    swift 異なるクラスからビューに追加

    前提・実現したいこと 一つのビューコントローラーにクラスを複数個置き、 仮にクラスAとクラスBとしたとき、クラスBからクラスAにオブジェクトを追加したいです。 該当のソー

  • 解決済

    Swiftのオブジェクト感知

    前提・実現したいこと 3つ程度オブジェクトを設置して (上記のオブジェクトは移動させられます) touchBegan でタップしたところにある オブジェクトを検出したいです

  • 解決済

    Swift3 カスタムボタンを使ってゴミ箱を作りたい

    Swift3でiOSアプリを作っています。 ボタンを生成して動かす事は出来ました。 ボタンをゴミ箱まで移動させて、そのボタンを削除したいと思います。 そこで移動中のカスタ

  • 解決済

    【Swift】CATransform3Dを使って画像を回転したい

    CATransform3Dを使って、画像をy軸もしくはx軸に回転する方法を教えてください。

  • 解決済

    iOSのカスタムキーボードでスワイプ入力を実装したい

    ※詳細な情報が不足しているので、確認次第追記します 当方Swift初心者ですが、XCode8.2.1,Customkeyboard Extension,Swift3にてカスタム

  • 解決済

    ドラッグでビューを移動させたいです。

    iOSのアプリ開発を始めました。画面の中心にラベルを配置し、それをタッチしてドラッグするとラベルが移動するプログラムを作成しようとしています。しかし実行すると、ラベルの表示まではう

同じタグがついた質問を見る

  • Swift

    6717questions

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

  • Xcode

    3857questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。