簡體   English   中英

SwiftUI:不同視圖之間的數據共享

[英]SwiftUI: Data sharing between separate views

在視圖之間共享變量的最佳做法是什么? 我的應用程序只有一個視圖。 但是隨着它變得越來越復雜,我認為我應該將它分成幾個視圖。 還要分開方法。 我從這樣的事情開始:

struct ContentView: View {
    @State var str: String = "String"
    var body: some View {
        VStack(alignment: .leading) {
            Text(str)
            TextField("Input", text: $str)
            Button("button", action: { doSomething() })
        }.padding()
    }
    func doSomething() {
        str = str + " " + str
    }
}

並想 go 那里:

class GlobalVars: ObservableObject {
    @Published var str: String = "Initial String"
}
struct ContentView: View {
    @ObservedObject var globalvars = GlobalVars()
    var body: some View {
        VStack(alignment: .leading) {
            DisplayView()
            EditView()
            ControlView()
        }.padding()
    }
}
struct DisplayView: View {
    @Binding var str:  String
    var body: some View {
        Text(self.globalvars.str)
    }
}
struct EditView: View {
    @Binding var str:  String
    var body: some View {
        TextField("Input", text: self.$str)
    }
}
struct ControlView: View {
    @Binding var str:  String
    var body: some View {
        Button("button", action: { doSomething() })
    }
}
func doSomething() {
    @Binding var str:  String
    self.str = self.str + " " + self.str
}

我嘗試使用@Published、@ObservedObject 和@Binding。 但不明白。 感謝您提前提供任何指示。

有很多方法可以解決這個問題。

我的選擇可能是將綁定僅傳遞給您需要訪問的變量。 這可能看起來像這樣:

class GlobalVars: ObservableObject {
    @Published var str: String = "Initial String"
}
struct ContentView: View {
    @ObservedObject var globalvars = GlobalVars()
    var body: some View {
        VStack(alignment: .leading) {
            DisplayView(str: globalvars.str) //don't need a binding here since it doesn't get modified
            EditView(str: $globalvars.str)
            ControlView(str: $globalvars.str)
        }.padding()
    }
}
struct DisplayView: View {
    var str:  String //don't need a binding here since it doesn't get modified
    var body: some View {
        Text(str)
    }
}
struct EditView: View {
    @Binding var str:  String
    var body: some View {
        TextField("Input", text: $str)
    }
}
struct ControlView: View {
    @Binding var str:  String
    var body: some View {
        Button("button", action: { doSomething() })
    }
    
    func doSomething() {
        str = str + " " + str
    }
}

請注意,現在在ContentView中,有一個參數傳遞給每個子視圖,其中包含到GlobalVars str屬性的綁定(使用$符號)。

此外, doSomething被移入ControlView的主體


您也可以使用 EnvironmentObject 來處理這個問題。 我個人不太喜歡這種方法,因為我寧願明確地看到我的參數的去向。 它還使子視圖可以訪問整個 ObservableObject,這並不是必需的。 但是,它向您展示了校長:

class GlobalVars: ObservableObject {
    @Published var str: String = "Initial String"
}
struct ContentView: View {
    @ObservedObject var globalvars = GlobalVars()
    var body: some View {
        VStack(alignment: .leading) {
            DisplayView()
            EditView()
            ControlView()
        }.padding()
        .environmentObject(globalvars)
    }
}
struct DisplayView: View {
    @EnvironmentObject var globalvars : GlobalVars
    var body: some View {
        Text(globalvars.str)
    }
}
struct EditView: View {
    @EnvironmentObject var globalvars : GlobalVars
    var body: some View {
        TextField("Input", text: $globalvars.str)
    }
}
struct ControlView: View {
    @EnvironmentObject var globalvars : GlobalVars
    var body: some View {
        Button("button", action: { doSomething() })
    }
    
    func doSomething() {
        globalvars.str = globalvars.str + " " + globalvars.str
    }
}

請注意,現在, globalvars通過放置在具有.environmentObject的視圖層次結構中傳遞給子項。 每個子視圖都可以通過聲明@EnvironmentObject var globalvars: GlobalVars


您還可以做一種混合 model ,其中您將 ObservableObject 作為參數顯式傳遞給子視圖:

struct ContentView: View {
    @ObservedObject var globalvars = GlobalVars()
    var body: some View {
        VStack(alignment: .leading) {
            DisplayView(globalvars: globalvars)
        }.padding()
        .environmentObject(globalvars)
    }
}

struct DisplayView: View {
    @ObservedObject var globalvars : GlobalVars
    var body: some View {
        Text(globalvars.str)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM