👏
SwiftUI リストに値を追加してUIを更新する LocalState
参考サイト
まずボタンを押しても動かなかったサンプルコード
import SwiftUI
struct GoodByeUIKitApp2: View {
private var fruits = ["りんご", "オレンジ", "バナナ"]
var body: some View {
Button("押すとリストが更新されなかった", action: {
fruits.append("ナシ")
})
List {
ForEach(0 ..< fruits.count) { index in
Text(fruits[index])
}
}
}
}
@main
struct GoodByeUIKitApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
GoodByeUIKitApp2() // 一番最初に表示されるView: これから作成します
}
}
}
原因1
@Stateを状態の変数の先頭につける
@State private var fruits = ["りんご", "オレンジ", "バナナ"]
Dart(Flutter)の場合、final変数でもlistの場合はappend出来てしまうので非常に便利だと思った。
原因2
明示的な id の指定: ForEach 内で id パラメータを指定することで、要素の一意性が保証され、更新が正しく行われる
ForEach(fruits.indices, id: \.self) { index in
Text(fruits[index])
}
動作する全コード
import SwiftUI
struct GoodByeUIKitApp2: View {
@State private var fruits = ["りんご", "オレンジ", "バナナ"]
var body: some View {
Button("動作するコード", action: {
fruits.append("ナシ")
})
List {
ForEach(0 ..< fruits.count) { index in
Text(fruits[index])
}
}
}
}
@main
struct GoodByeUIKitApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
GoodByeUIKitApp2() // 一番最初に表示されるView: これから作成します
}
}
}
次回はこのコードはShared Stateを使用する。
Discussion