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

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

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

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

Swift

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

Q&A

解決済

1回答

1197閲覧

SwiftUI:ForEachで生成したButtonごとに、.sheetを表示させる内容を変えたい

Racc

総合スコア4

Xcode

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

Swift

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

0グッド

0クリップ

投稿2023/02/07 05:12

実現したいこと

ForEachで生成したButtonごとに、表示させる.sheetの内容を変えたい。

前提

Swift/Xcodeでゲーム開発をしています。
今回は、バトルログ画面でターン配列ごとにそのターンの詳細を見れるようにしたいと思っています。

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

ForEachで配列の[turns]ごとにButtonが生成されており、.sheet{}内でBattleModalView()を呼び出し、引数に表示したいString(infoText: infoText)を渡しています。BattleModalView()のinfoText:Stringは@Stateで宣言しているため、再描画されるはずだと思ったのですが、いつ生成されたButtonを押しても配列の最初(turns[1])の情報が描画されたBattleModalView()になります。これを、turns[2]で生成したButtonを押したらturns[2].infoText、turns[10]で生成したButtonを押したらturns[10].infoTextの情報がBattleModalView()に表示されるようにしたいです。

該当のソースコード

Swift

1import SwiftUI 2import Liquid 3 4// 省略 5 6struct TurnsView: View { 7 var turns: [Turns] 8 @State private var showingModal = false 9 10 var body:some View { 11 ForEach (0 ..< (turns.count ?? 0)) { index in 12 let i = index 13 14 // 省略 15 Button(action: { 16 self.showingModal.toggle() 17 }) { 18 Text("ターンの詳細を見る") 19 }.sheet(isPresented: $showingModal) { 20 let thisInfo = turns[i].infoText 21 BattleModalView(infoText: thisInfo) 22 } 23 .font(.system(size: 12)) 24 .frame( maxWidth: .infinity, alignment: .leading) 25 .padding(.leading, 57) 26 .foregroundColor(.blue) 27 .fontWeight(.bold) 28 29// 省略 30 } 31 } 32 } 33} 34 35// 省略 36 37struct BattleModalView: View { 38 @State var infoText: String 39 var body: some View { 40 41 ScrollView { 42 43 Text(infoText) 44 .font(.system(size: 8)) 45 .foregroundColor(.black) 46 .fontWeight(.bold) 47 .padding() 48 49 } 50 .frame(maxWidth: .infinity, maxHeight: .infinity) 51 52 } 53}

試したこと

検索、chatGPTへの質問など色々調べましたが、全く同じケースが出てきませんでした。。

補足情報(FW/ツールのバージョンなど)

Version 14.2

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

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

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

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

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

guest

回答1

0

自己解決

自己解決しました。
結論、ForEachで生成しようとしていたオブジェクトを別のView()を作って分割し、ForEachでView()を呼ぶ形にしました。
以下ソースコードです。

// 省略 struct TurnsView: View { var turns: [Turns] var body:some View { ForEach (0 ..< (turns.count ?? 0)) { index in TurnsPanelView(turns: turns[index]) } // ForEach Text("") } // body } struct TurnsPanelView: View { var turns: Turns @State private var showingModal = false @State var selectIndex: Int = 0 var body: some View { // 省略 Button(action: { self.selectIndex = turns.thisTurn self.showingModal.toggle() }) { Text("ターンの詳細を見る") } .tag(turns.thisTurn) .font(.system(size: 12)) .frame( maxWidth: .infinity, alignment: .leading) .padding(.leading, 57) .foregroundColor(.blue) .fontWeight(.bold) .sheet(isPresented: $showingModal) { BattleModalView(infoText: turns.infoText) } // 省略 } } } // 省略 struct BattleModalView: View { @State var infoText: String var body: some View { ScrollView { Text(infoText) .font(.system(size: 8)) .foregroundColor(.black) .fontWeight(.bold) .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) } }

投稿2023/02/08 00:30

Racc

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問