🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Xcode

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

Swift

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

Q&A

解決済

1回答

3192閲覧

SwiftでUIImageにタグを設定しタップしたときにUIImageを変更したい

mum

総合スコア17

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/12/08 01:43

実現したいこと

Xcode11.1でStoryBoardを使わずに神経衰弱のようなゲーム.appを作っています。

発生している問題

UIImageをViewに25個表示させ、それぞれにタグを設定することができたのですが、GestureTapメソッドでタグを判定し、タグごとにUIImageを変更する方法がわかりません。
vw(UIImageViewのオブジェクト).imageでUIImageを変更すると最後に生成されたオブジェクトだけが変更されます。
試行錯誤を繰り返したのですが、わかりません。
心優しき方、ご教授願います。

該当のソースコード

swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 // UIImageViewインスタンス作成 6 var vw: UIImageView! 7 // フラグ Trueが表, falseが裏 8 var flg = false 9 // タグを配列に格納 10 var tgArray: [Int] = [] 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 makeImage() 16 } 17 18 // イメージビュー作成 19 func makeImage() { 20 21 let length = 65 22 var tg = 0 23 24 // イメージビュー複数作成 25 for y in 0...4 { 26 27 let ay = 150 + (length * y) 28 29 for x in 0...4 { 30 31 let ax = 38 + (70 * x) 32 33 // イメージビューの設定 34 vw = UIImageView(frame: CGRect(x: ax, y: ay, width: length, height: length)) 35 vw.image = UIImage(named: "mum01_shadow") 36 vw.tag = tg 37 tgArray.append(tg) 38 tg += 1 39 view.addSubview(vw) 40 41 // タップジェスチャーの設定 42 vw.isUserInteractionEnabled = true 43 44 let ges = UITapGestureRecognizer( 45 target: self, 46 action: #selector(gestureTap(sender:))) 47 vw.addGestureRecognizer(ges) 48 49 } 50 51 } 52 } 53 54 // イメージをタップした時の処理 55 @objc func gestureTap(sender: UITapGestureRecognizer) { 56 print(sender.view!.tag) 57 58 if flg == false { 59 switch sender.view!.tag { 60 case 0: 61// vw.image = UIImage(named: "mum01") 62 flg = true 63 case 1: 64 vw.image = UIImage(named: "mum01") 65 flg = true 66 case 2: 67 vw.image = UIImage(named: "mum01") 68 flg = true 69 case 3: 70 vw.image = UIImage(named: "mum01") 71 flg = true 72 case 4: 73 vw.image = UIImage(named: "mum01") 74 flg = true 75 case 5: 76 vw.image = UIImage(named: "mum01") 77 flg = true 78 case 6: 79 vw.image = UIImage(named: "mum01") 80 flg = true 81 case 7: 82 vw.image = UIImage(named: "mum01") 83 flg = true 84 case 8: 85 vw.image = UIImage(named: "mum01") 86 flg = true 87 case 9: 88 vw.image = UIImage(named: "mum01") 89 flg = true 90 case 10: 91 vw.image = UIImage(named: "mum01") 92 flg = true 93 case 11: 94 vw.image = UIImage(named: "mum01") 95 flg = true 96 case 12: 97 vw.image = UIImage(named: "mum01") 98 flg = true 99 case 13: 100 vw.image = UIImage(named: "mum01") 101 flg = true 102 case 14: 103 vw.image = UIImage(named: "mum01") 104 flg = true 105 case 15: 106 vw.image = UIImage(named: "mum01") 107 flg = true 108 case 16: 109 vw.image = UIImage(named: "mum01") 110 flg = true 111 case 17: 112 vw.image = UIImage(named: "mum01") 113 flg = true 114 case 18: 115 vw.image = UIImage(named: "mum01") 116 flg = true 117 case 19: 118 vw.image = UIImage(named: "mum01") 119 flg = true 120 case 20: 121 vw.image = UIImage(named: "mum01") 122 flg = true 123 case 21: 124 vw.image = UIImage(named: "mum01") 125 flg = true 126 case 22: 127 vw.image = UIImage(named: "mum01") 128 flg = true 129 case 23: 130 vw.image = UIImage(named: "mum01") 131 flg = true 132 case 24: 133 vw.image = UIImage(named: "mum01") 134 flg = true 135 default: 136 break 137 } 138 139 } else { 140 vw.image = UIImage(named: "mum01_shadow") 141 flg = false 142 } 143 } 144

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

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

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

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

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

guest

回答1

0

ベストアンサー

makeImageの中でvwに対してUIImageViewのインスタンスを繰り返し入れているので、最後に作ったものだけがvwに入っています。
このため、switch文でどのタグがきても、最後のもののimageを変更しています。
やりたいのはそのImageViewのimageを変えることだと思うので、

// イメージをタップした時の処理 @objc func gestureTap(sender: UITapGestureRecognizer) { print(sender.view!.tag) guard let imageView = sender.view as? UIImageView else { return } // 追加 (以下略)

というようにしてimageViewに対象のUIImageViewをとりだして、それのimageを変えるとよいです。

なお、今は表示できているように見えているようですが、frameの位置を指定するだけではオブジェクトの表示位置を固定できません。auto layoutの設定をするなどする必要があります。

flagも画像分用意する必要があるでしょう。

ひとつひとつ順にやっていってみてください。

投稿2019/12/08 11:10

eytyet

総合スコア803

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

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

mum

2019/12/08 14:15

ありがとうございます!動きました! guard letってこういう使い方ができるんですね。 これは、sender.viewがUIViewクラスなので、UIImageViewにダウンキャストして、nilの場合はreturn。 nilじゃない場合はimageViewの定数に代入されて、普通にUIViewのタグで判定して処理することができるようになるということであってますでしょうか。勉強中ですいません。 auto layoutも調べてやってみます。 flagも画像分必要になるんですね。 いろいろ教えていただきありがとうございます。 勉強になります。
eytyet

2019/12/08 15:01

だいたいあっています。sender.view as? UIImageView という書き方は、sender.viewが示すオブジェクトがUIImageViewであるかを確認して、違ったらnilにします。合っていたら、imageViewにそのオブジェクトがUIImageView型として入ります。"オプショナル型"という概念が混ざっているので、それも学ぶとより理解できますが、ここではguardを使って型が合うときだけ実行するのにこういう書き方が使えるということを理解できれば良いかと思います。 自分でgestureTapを呼び出すジェスチャーリコグナイザを作成し、UIImageViewにaddGestureRecognizerで登録しているので、gestureTapはそのUIImageView上でジェスチャーが発生したときに呼ばれます。このとき引数のsender.viewにはそのUIImageViewが入って来ます。そのようにしか登録していないので、今のところは、sender.viewはUIImageView以外である可能性はありません。なので、guardでリターンすることはない筈です。ですが、定義上sender.viewの型はUIView型で、それ以外がくる可能性を否定できないので、このような書き方をしておくと安全(不用意なクラッシュを防げる)です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問