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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

データバインディング

データソースと、アプリケーションやウェブページ(ウェブアプリケーション)のユーザインタフェースを静的または動的に結合する技術です。

Swift

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

配列

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

Q&A

解決済

1回答

3278閲覧

【SwiftUI】構造体配列を追加した際の挙動について

Jene

総合スコア13

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

データバインディング

データソースと、アプリケーションやウェブページ(ウェブアプリケーション)のユーザインタフェースを静的または動的に結合する技術です。

Swift

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

配列

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

0グッド

0クリップ

投稿2021/08/29 08:25

編集2021/08/29 09:51

前提・実現したいこと

SwiftUIにて、構造体配列を使ってリストを実装しようとしています。また、リストは「.indices」を使用して表示したいです。
「.indices」を採用する理由としては、今後テキストデータをバインディングさせたい為です。
以下のコードで想定している動作の流れとしては、【ボタンを押下】→【配列に構造体要素を追加】→【リストで全要素を表示】を目指しております。

該当のソースコード

#構造体作成。 struct SampleModel: Identifiable { var id = UUID() var value :String var text: String init(value:String, text: String){ self.value = value self.text = text } } #ObservableObjectで配列を用意。 class Data: ObservableObject { @Published var array: [SampleModel] init(){ self.array = [SampleModel(value: "356", text: "")] #テスト用初期要素 } } #以下、Viewを作成。 struct ContentView: View { @ObservedObject var data: Data = Data() var body: some View { VStack{                         #ボタンを用意。押下時に要素を追加。 Button(action: { data.array.append(SampleModel(value: "1234", text: "")) debugPrint("追加") }, label: { Text("Button") }) #テスト用リスト #この方式の場合、ボタン押下と同時にリストのレコードが追加される。 #この場合データバインディングの実装が難しい? List { ForEach(self.data.array) { sample in Text(sample.value) } } #目指している表示方法 #ボタンを押下してもレコードは追加されない。(初めから入っているテスト用初期要素は表示される。) List { ForEach(self.data.array.indices) { index in Text(data.array[index].value) } } } } }

試したこと

どういった原因で追加更新されないのかわからず、手詰まりの状態です。
初歩的な質問で恐縮ですが、ご教授頂きたいです。

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

Xcode 12.5.1
iOS 14.0向け

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

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

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

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

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

hoshi-takanori

2021/08/29 09:26

せっかく SampleModel に id があるのだから、それを使うべきでは。(.indices だと、リストの途中に項目を追加や削除した時に index がずれておかしくなる可能性があります。) あと、ForEach.init などの .init は省略可能というか、省略するのが一般的です。
Jene

2021/08/29 09:52

このやり方ではidを使えてないから配列の管理が出来ていないという認識でいいでしょうか。自分の中では使っている認識でいました…。もし可能でしたらどのようにすればidを使っている状態になるのかご教授頂けますでしょうか。 .indicesの利用デメリット情報ありがとうございます。データバインディングさせる際、.indicesを使わない手段もあるのでしょうか。知識不足で大変恐縮ですが教えて頂けますと幸いです。
hoshi-takanori

2021/08/29 10:16

ごめんなさい、データバインディングするには index が必要かもですね。ちょっと考えさせてください。 ちなみに、編集は List 上でそのまま行いますか? それとも、別画面に遷移して行いますか?
Jene

2021/08/29 22:52

ありがとうございます。 編集はリスト上で行うことを想定しております。よろしくお願い致します。
guest

回答1

0

ベストアンサー

追加や削除を実装するには ForEach の id: には SampleModel の id を渡す必要がありますが、一方で index がないとデータバインディングに困りますよね。

というわけで、両方使える enumerated を使うと良いでしょう。ただし、id: には .offset ではなく .element.id を渡す必要があります。
参考: SwiftUIのForEachでViewを繰り返し表示|TAAT|note

swift

1List { 2 ForEach(Array(data.array.enumerated()), id: .element.id) { index, sample in 3 VStack { 4 Text(sample.value) 5 TextField("Text", text: $data.array[index].text) 6 } 7 } 8 .onDelete { data.array.remove(atOffsets: $0) } 9}

投稿2021/08/29 11:58

編集2021/08/29 12:02
hoshi-takanori

総合スコア7895

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

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

Jene

2021/08/29 23:38 編集

enumeratedというものがあるんですね。ご丁寧な回答ありがとうございます。動作を確認したところイメージしていた動きが得られました。大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問