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

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

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

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

Swift

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

Q&A

1回答

275閲覧

Xcodeでのエラーについて

yokuyoku

総合スコア13

Xcode

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

Swift

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

0グッド

0クリップ

投稿2023/05/13 07:49

XcodeでswiftUIを使って写真の4択クイズを作ろうとしているのですが、下の星で挟まれている部分のコードで、

Thread 1: Fatal error: Index out of range

というエラーが出てしまいます。

配列の要素も四つ以上あるので問題ない気がして、自分ではわかりかねているので、わかる方いたら教えていただきたいです。

よろしくお願いします。
下が、問題のコードです。

import SwiftUI

struct ContentView: View {
let imageFileNames = ["CorrectImage1", "CorrectImage2", "CorrectImage3", "CorrectImage4", "WrongImage1", "WrongImage2", "WrongImage3", "WrongImage4"]

@State private var gameCount = 0 @State private var correctImageFileName = "" @State private var chosenImageFileNames: [String] = [] @State private var showingAlert = false @State private var alertTitle = "" var body: some View { VStack { if gameCount < 20 { VStack { ForEach(0..<2) { rowIndex in HStack { ForEach(0..<2) { columnIndex in ☆☆☆☆ let chosenImage = chosenImageFileNames[rowIndex * 2 + columnIndex]  ☆☆☆☆ Button(action: { if chosenImage == correctImageFileName { alertTitle = "正解!" gameCount += 1 } else { alertTitle = "間違い!" } showingAlert = true }) { Image(chosenImage) .resizable() .frame(width: 100, height: 100) } .padding(20) } } .frame(maxWidth: .infinity) } } .alert(isPresented: $showingAlert) { Alert(title: Text(alertTitle), dismissButton: .default(Text("OK")) { if gameCount < 20 { selectImages() } }) } } else { Text("終了!") } } .onAppear { selectImages() } } func selectImages() { var chosenIndices = [Int]() let correctIndex = Int.random(in: 0..<imageFileNames.count) chosenIndices.append(correctIndex) correctImageFileName = imageFileNames[correctIndex] while chosenIndices.count < 4 { let randomIndex = Int.random(in: 0..<imageFileNames.count) if !chosenIndices.contains(randomIndex) { chosenIndices.append(randomIndex) } } chosenImageFileNames = chosenIndices.map { imageFileNames[$0] } }

}

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

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

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

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

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

guest

回答1

0

onAppearが動くタイミングを確認してみると良いと思いました。
そのためのコードを下に記載しておきますね。
コードの中に記載したコメントも読んでみてください。

swift

1import SwiftUI 2 3struct ContentView: View { 4 let imageFileNames = ["CorrectImage1", "CorrectImage2", "CorrectImage3", "CorrectImage4", "WrongImage1", "WrongImage2", "WrongImage3", "WrongImage4"] 5 @State private var gameCount = 0 6 @State private var correctImageFileName = "" 7 @State private var chosenImageFileNames: [String] = [] 8 @State private var showingAlert = false 9 @State private var alertTitle = "" 10 var body: some View { 11 VStack { 12 if gameCount < 20 { 13 VStack { 14 ForEach(0..<2) { rowIndex in 15 HStack { 16 ForEach(0..<2) { columnIndex in 17 // *** 動く順番を確認するためにfuncにしました。 18 //let chosenImage = chosenImageFileNames[rowIndex * 2 + columnIndex] 19 let chosenImage = getchosenImage(rowIndex, columnIndex) 20 Button(action: { 21 if chosenImage == correctImageFileName { 22 alertTitle = "正解!" 23 gameCount += 1 24 } else { 25 alertTitle = "間違い!" 26 } 27 showingAlert = true 28 }) { 29 Image(chosenImage) 30 .resizable() 31 .frame(width: 100, height: 100) 32 } 33 .padding(20) 34 } 35 } 36 .frame(maxWidth: .infinity) 37 } 38 } 39 .alert(isPresented: $showingAlert) { 40 Alert(title: Text(alertTitle), dismissButton: .default(Text("OK")) { 41 if gameCount < 20 { 42 selectImages() 43 } 44 }) 45 } 46 } else { 47 Text("終了!") 48 } 49 } 50 .onAppear { 51 selectImages() 52 } 53 } 54 // *** funcを追加しました。 55 // *** onAppearのselectImagesよりも前にgetchosenImageが動いていることがわかると思います。 56 func getchosenImage(_ rowIndex: Int, _ columnIndex: Int) -> String { 57 print("getchosenImage") 58 guard !chosenImageFileNames.isEmpty else { 59 return "適当な文字列です。" 60 } 61 // selectImagesが動く前はchosenImageFileNamesの要素数は0ですので、この配列の0番目を参照して「Index out of range」のエラーになっていると思います。 62 return chosenImageFileNames[rowIndex * 2 + columnIndex] 63 } 64 func selectImages() { 65 // printを追加しました。 66 print("selectImages") 67 var chosenIndices = [Int]() 68 let correctIndex = Int.random(in: 0..<imageFileNames.count) 69 chosenIndices.append(correctIndex) 70 correctImageFileName = imageFileNames[correctIndex] 71 while chosenIndices.count < 4 { 72 let randomIndex = Int.random(in: 0..<imageFileNames.count) 73 if !chosenIndices.contains(randomIndex) { 74 chosenIndices.append(randomIndex) 75 } 76 } 77 chosenImageFileNames = chosenIndices.map { imageFileNames[$0] } 78 } 79}

投稿2023/05/13 08:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問