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

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

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

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

Swift

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

Q&A

解決済

1回答

486閲覧

SwiftUI 配列に追加した文字列をリスト表示する方法を教えてください

FirstBeginner

総合スコア11

Xcode

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

Swift

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

0グッド

0クリップ

投稿2022/09/12 10:18

前提

SwiftUIで、配列にデータを追加しながらリアルタイムでリストが増えていく機能を実装したいのですが上手くいきません。

実現したいこと

TextFieldに文字を入力するとtextlist:[String]に格納され、リストが増えていく機能を実装したいです。
また、自分は配列に格納していく方法しか思いつきませんでしたが、他にこのような機能を実現する方法があったら教えていただきたいです。
Realm、firebaseは現在勉強中です。

該当のソースコード

SwiftUI

1import SwiftUI 2 3struct DataList: View { 4 @State var textlist:[String]=[] 5 @State var text="" 6 var body: some View { 7 VStack{ 8 TextField("ここに入力", text: $text) 9 Button(action:{ 10 textlist.append(text) 11 }) { 12 Text("保存") 13 } 14 List { 15 ForEach(0..<textlist.count){index in 16 Text(textlist[index]) 17 } 18 } 19 } 20 } 21}

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

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

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

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

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

guest

回答1

0

ベストアンサー

Section 5 Make the List Dynamic
https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

idを指定すると良いと思いました。

swift

1ForEach(0..<textlist.count, id: \.self){index in 2 Text(textlist[index]) 3}

追記です。

コメントありがとうございます。

これはなぜか説明していただければ幸いです。

Creates an instance that uniquely identifies and creates views across updates based on the provided key path to the underlying data’s identifier.
(機械翻訳)基礎となるデータの識別子への提供されたキーパスに基づいて、更新にわたってビューを一意に識別して作成するインスタンスを作成します。

https://developer.apple.com/documentation/swiftui/foreach/init(_🆔content:)-82hm4

SwiftUIの内部実装まで把握していないので合っているかわからないですが・・
リストを動的に追加したり、削除したりするのに、SwiftUIが要素を一意に識別できるようにしてあげる必要があるみたいです。
そのための情報がidみたいです。

例えば、下のサンプルコードはidが一意ではないので、
([1, 2, 1, 2, 1]なので1が3つあるし、2が2つある)
4番目の要素をスワイプして削除すると、
2番目の2と3番目の1が入れ替わって?
[1, 1, 2, 1]
の順番で表示されます。

要素を一意に識別できないとこのような不都合があるので、
SwiftUIに要素を一意に識別できるための情報(id)を渡してあげる必要があるみたいです。

*idを渡さないとSwiftUIは何も識別できないことになると思います
*selfは要素自身ですので、サンプルコードの場合ですと、「1」とか「2」とかの値になります

swift

1import SwiftUI 2 3struct ContentView: View { 4 @State var array: [Int] = [1, 2, 1, 2, 1] 5 var body: some View { 6 List { 7 ForEach(array, id: \.self) { int in 8 Text("\(int)") 9 } 10 .onDelete(perform: perform) 11 } 12 } 13 func perform(ind: IndexSet) { 14 array.remove(atOffsets: ind) 15 print(array) 16 } 17}

It’s important that the id of a data element doesn’t change, unless SwiftUI considers the data element to have been replaced with a new data element that has a new identity. If the id of a data element changes, then the content view generated from that data element will lose any current state and animations.
(機械翻訳)SwiftUI がデータ要素を新しい ID を持つ新しいデータ要素に置き換えたと考えない限り、データ要素の ID が変更されないことは重要です。データ要素のIDが変更された場合、そのデータ要素から生成されたコンテンツビューは、現在の状態とアニメーションを失います。

https://developer.apple.com/documentation/swiftui/foreach/init(_🆔content:)-82hm4

機械翻訳で表現は微妙ですし、
今回とはちょっと異なるケースかもしれませんが、
「現在の状態とアニメーションを失います。」
と記載されています。
idを渡してあげないと内部の配列に対して要素を追加・削除しても、画面にその内容が反映されないということだと思います。


SwiftUIのチュートリアルも実践してみるとより理解が深まると思うのですが、
idをForEachに直接記述する以外にも、データにidプロパティを持たせることもできるみたいです。
https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

投稿2022/09/12 13:51

編集2022/09/16 11:27
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

FirstBeginner

2022/09/16 09:39

解決しました! これはなぜか説明していただければ幸いです。
FirstBeginner

2022/09/16 11:31

なるほど!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問