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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1084閲覧

Swift 二次元配列を使ったボタンの配置とタグについて

nyansuke373

総合スコア7

Swift

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/03/23 15:28

編集2020/03/23 15:42

前提・実現したいこと

類似アプリを参考に3×3のパズルアプリを作成しております。
0〜8のボタンで二次元配列を使ってボタンの位置を決めているのですが、どのボタンを押しても(x: 0,y: 0)で渡されてしまい、どのように設定すれば位置が決まるのかについて知恵をお借りできればと思います。

発生している問題・エラーメッセージ

② 49行目moveButtonメソッドを実行したとき、button.tag引数がどのように渡されていくのか
どのボタンを押しても(x: 0,y: 0)で渡してしまっているので、それを解決するにはどうやったら良いか。(どう記述すれば良いか)

@IBAction func movebutton(_ button: UIButton) { //ここで二次元配列にしたy,xの値が0になっている。 for y in 0..<map.count { for x in 0..<map.count { if map[y][x].tag == button.tag { //0~8のどのボタンを押しても[0][0]になる  searchAndMove(x: x, y: y) return } } } }

該当のソースコード

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var button0: UIButton! 6 @IBOutlet weak var button1: UIButton! 7 @IBOutlet weak var button2: UIButton! 8 @IBOutlet weak var button3: UIButton! 9 @IBOutlet weak var button4: UIButton! 10 @IBOutlet weak var button5: UIButton! 11 @IBOutlet weak var button6: UIButton! 12 @IBOutlet weak var button7: UIButton! 13 @IBOutlet weak var button8: UIButton! 14 @IBOutlet weak var colorView: UIView! 15 //ボタンをUIButtonl型で初期化 16 var buttons = [UIButton]() 17 //ポイントをCGポイント型で初期化 18 var points = [CGPoint]() 19 //mapを二次元配列UIButton型で初期化 20 var map = [[UIButton]]() 21 22 override func viewDidLoad() { 23 super.viewDidLoad() 24 25 buttons.append(button0) 26 buttons.append(button1) 27 buttons.append(button2) 28 buttons.append(button3) 29 buttons.append(button4) 30 buttons.append(button5) 31 buttons.append(button6) 32 buttons.append(button7) 33 buttons.append(button8) 34 35 for button in buttons { 36 points.append(button.frame.origin) 37 } 38 reset() 39 } 40 41 42 43 @IBAction func movebutton(_ button: UIButton) { 44 //yとXの位置を探す。 ボタンタグと同じであれば、searchAndMoveにyとXの値を渡す。 45 for y in 0..<map.count { 46 for x in 0..<map.count { 47 if map[y][x].tag == button.tag {  //ここでy,xの値が0になっている。 48 searchAndMove(x: x, y: y) 49 return 50 } 51 } 52 } 53 } 54 55 56 57 @IBAction func startButton(_ sender: Any) { 58 reset() 59 } 60 61 //リセットメソッドviewDidLoad時に呼ばれる 62 private func reset(){ 63 colorView.isHidden = true 64 button8.isHidden = true 65 buttons = buttons.shuffled() 66 67 for button in buttons { 68 points.append(button.frame.origin) 69 } 70 71 for index in 0..<buttons.count { 72 buttons[index].frame.origin = points[index] 73 } 74 //ボタンを二次元配列で配置 75 map = [[UIButton]]() 76 map.append([buttons[0], buttons[1], buttons[2]]) 77 map.append([buttons[3], buttons[4], buttons[5]]) 78 map.append([buttons[6], buttons[7], buttons[8]]) 79 } 80 81 //hiddenにしていたbutton8を探して入れ替える 82 private func searchAndMove(x: Int, y: Int) { 83 //左 84 if x - 1 >= 0, map[y][x - 1] == button8 { 85 xMove(beginX: x, endX: x - 1, y: y) 86 //右 87 } else if x + 1 <= 2, map[y][x + 1] == button8 { 88 xMove(beginX: x, endX: x + 1, y: y) 89 //下 90 } else if y - 1 >= 0, map[y - 1][x] == button8 { 91 yMove(x: x,beginY: y, endY: y - 1) 92 //上 93 } else if y + 1 <= 2, map[y + 1][x] == button8 { 94 yMove(x: x, beginY: y, endY: y + 1) 95 } 96 } 97 98 //x座標の動き 99 private func xMove(beginX: Int, endX: Int, y: Int) { 100 UIView.animate(withDuration: 0.2, animations: { 101 //座標の入れ替え 102 let origin = self.map[y][endX].frame.origin 103 self.map[y][endX].frame.origin = self.map[y][beginX].frame.origin 104 self.map[y][beginX].frame.origin = origin 105 }, completion: { _ in 106 //ボタンの入れ替え 107 let button = self.map[y][endX] 108 self.map[y][endX] = self.map[y][beginX] 109 self.map[y][beginX] = button 110 self.judge() 111 }) 112 } 113 //y座標の動き 114 private func yMove(x: Int,beginY: Int, endY: Int) { 115 UIView.animate(withDuration: 0.2, animations: { 116 //座標の入れ替え 117 let origin = self.map[endY][x].frame.origin 118 self.map[endY][x].frame.origin = self.map[beginY][x].frame.origin 119 self.map[beginY][x].frame.origin = origin 120 }, completion: { _ in 121 //ボタンの入れ替え 122 let button = self.map[endY][x] 123 self.map[endY][x] = self.map[beginY][x] 124 self.map[beginY][x] = button 125 self.judge() 126 }) 127 } 128 129 //クリア判定 mapの位置 130 private func judge() { 131 if map[0][0] == button0, map[0][1] == button1, map[0][2] == button2, 132 map[1][0] == button3, map[1][1] == button4, map[1][2] == button5, 133 map[2][0] == button6, map[2][1] == button7, map[2][2] == button8 { 134 colorView.isHidden = false 135 button8.isHidden = false 136 137 let alert = UIAlertController(title: "クリア",message: "おめでとう!", preferredStyle: .alert) 138 let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil) 139 alert.addAction(alertAction) 140 present(alert, animated: true, completion: nil) 141 } 142 } 143} 144

試したこと

座標でボタンの位置を初期化しています。下の図で言う「0」ボタンは2次元配列でいうところのx,y = [2][0]となるように作っております。
しかしデバックログを見ると、どれもx,y = [0][0]となっており取得したい値と異なっている。

補足情報

●やっている内容
1.ボタンを9つOutret接続
2.配列に0〜8ボタンを代入
3.moveButtonメソッドで xとyの値を決める
4.searchAndMoveメソッドにxとyの値を与えて上下左右の座標を確認する
5.もし、上記4.で確認した座標に、hiddenにしている「8」ボタンがある場合入れ替える
6.座標の入れ替えと、ボタンの入れ替えをxMove,yMoveで行なっています。
7.クリア判定 mapで示した座標とボタンの位置が等しい時、hiddenにしている「8」ボタンが現れ、クリアメッセージが出る。
3. 期待する挙動(必須項目)
49行目 moveButtonメソッドを押したとき、引数をbutton.tagから取る。
(x: 0,y: 0)で渡してはダメなので、それを解決するにはどうやったら良いか。(どう記述すれば良いか)を知りたいです。↓画像moveBottonメソッド(x: 0,y: 0)を渡してしまっているイメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

あらかじめ、各ボタンにtagは設定していますでしょうか。

Storyboardからでもいいですが、viewDidLoad()に次の行を足しただけで動きましたよ。

Swift

1 super.viewDidLoad() 2 // ここから 3 button0.tag = 0 4 button1.tag = 1 5 button2.tag = 2 6 button3.tag = 3 7 button4.tag = 4 8 button5.tag = 5 9 button6.tag = 6 10 button7.tag = 7 11 button8.tag = 8 12 // ここまで 13 buttons.append(button0) 14

16ゲームの9つ版ですよね?

投稿2020/03/23 16:12

TsukubaDepot

総合スコア5086

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

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

nyansuke373

2020/03/23 16:20

ご回答ありがとうございました!ご指摘の通りで動きました。 Storyboardの方ばかりに頭が行ってしまっていて、こう見るととっても単純なところで詰まってしまっていたのですね。。16ゲームの9つ版です!
TsukubaDepot

2020/03/23 16:38

思わずハマってしまいました.. ところで、reset()の中に for button in buttons { points.append(button.frame.origin) } がありますが、これは不要じゃないですか? リセットするたびにpointが増殖してしまいます。 あと、ピースは無作為に入れ替えても解ける、という保証はあるんでしたっけ? どうしても解けない時があるのですが、それは私の努力がたりないだけでしょうか http://www.ne.jp/asahi/aaa/tach1394/delphi/0005/03.htm。
nyansuke373

2020/03/23 16:48

ご指摘ありがとうございます。ご指摘の通り、pointに関する記述は不要でしたね。 ピースについてシャッフルを考えないとダメでしたね。参考にさせていただきます! 親切なご回答、ありがとうございました。
TsukubaDepot

2020/03/23 16:49

私も色々と参考になるところがあって良い勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問