web-dev-qa-db-ja.com

ObservedObjectをネストされた子ビューに渡すSwiftUI(SwiftUIデータフロー)

@ObservedObject変数を渡すことがネストされた子ビューで機能しない理由を理解しようとしています。データを渡すことはできますが、変更は@ObservedObject変数が作成されたルートビューにのみ反映されます。変更はサブビューには表示されません。 Appleドキュメント(Xcodeベータ5向けに更新されています))を見ると、答えは、環境オブジェクトから正しいインデックスを取得するために、環境オブジェクトと通常の変数の両方を作成することです。これがりんごです

@ObservedObjectを使用して複数のビューから変数を参照できることを理解していますが、任意のビューからデータにアクセスできるようにする場合は、環境オブジェクトを使用する必要があります。したがって、@ ObservedObjectを渡すことは可能なはずだと思います。私が信じている問題は、ScreenTwoが@Binding変数をDetailsViewに渡しているため、問題が発生していることです。これを解決するには、@ ObservedObject全体を渡し続ける必要があると思いますが、適切なインデックスを取得するために、ある種の通常の変数が必要になります。

これらはすべてもっと簡単なはずです。

import SwiftUI
import Combine

struct Sport: Identifiable{
    var id = UUID()
    var name : String
    var isFavorite = false
    var school : String
}

final class SportData: ObservableObject  {
    @Published var store =
        [
            Sport(name: "soccer", isFavorite: false, school: "WPI"),
            Sport(name: "tennis", isFavorite: false, school: "WPI"),
            Sport(name: "swimming", isFavorite: true, school: "WPI"),
            Sport(name: "running", isFavorite: true, school: "RIT"),
    ]
}

struct Testing: View {
    @ObservedObject var sports = SportData()

    var body: some View {
        NavigationView{
            List{
                ForEach($sports.store){ sport in
                    NavigationLink(destination: ScreenTwo(sport: sport)){
                        HStack {
                            Text(sport.value.name)
                            Spacer()
                            Text(sport.value.isFavorite.description)
                        }
                    }
                }
            }
        }.navigationBarTitle("Settings")
    }
}

struct ScreenTwo : View{
    @Binding var sport : Sport

    var body: some View{
        NavigationLink(destination: DetailsView(sport: $sport)){
            Text(sport.isFavorite.description)
        }
    }
}

struct DetailsView: View {
    @Binding var sport : Sport

    var body: some View {
        Button(action: {
            self.sport.isFavorite.toggle()
            self.sport.name = "Ricky"
        }) {
            Text(sport.isFavorite.description)
            Text(sport.name)
        }
    }
}



#if DEBUG
struct Testing_Previews: PreviewProvider {
    static var previews: some View {
        Testing()
    }
}
#endif
8

ScreenTwoDetailsViewでは、_@EnviromentObject_ではなく_@ObservedObject_としてスポーツフィールドを定義する必要があります。また、TestingObservedObjectビューのNavigationLink(destination: ScreenTwo()).environmentObject(sport)で環境オブジェクトを設定します。

0
Arif Ulusoy