我试图理解为什么传递@ObservedObject变量对嵌套的子视图无效。可以传递数据,但是更改仅反映在创建@ObservedObject变量的根视图中。所做的更改不会显示在子视图中。查看Apple文档(已针对Xcode beta 5更新),答案似乎是创建一个环境对象和一个常规变量,以便从该环境对象中获取正确的索引。这是苹果example。
我的理解是,可以使用@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
答案 0 :(得分:2)
对于ObservableObject
,配对ObservedObject
使视图刷新,因此,为了解决有问题的任务,我建议采用以下方法:
演示
代码
import SwiftUI
import Combine
class Sport: ObservableObject, Hashable, Identifiable {
static func == (lhs: Sport, rhs: Sport) -> Bool {
lhs.name == rhs.name && lhs.isFavorite == rhs.isFavorite && lhs.school == rhs.school
}
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(isFavorite)
hasher.combine(school)
}
@Published var name : String
@Published var isFavorite = false
@Published var school : String
init(name: String, isFavorite: Bool, school: String) {
self.name = name
self.isFavorite = isFavorite
self.school = school
}
}
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 TestingObservedObject: View {
@ObservedObject var sports = SportData()
var body: some View {
NavigationView{
List{
ForEach(sports.store){ sport in
NavigationLink(destination: ScreenTwo(sport: sport)) {
HStack {
Text("\(sport.name)")
Spacer()
Text(sport.isFavorite.description)
}
}
.onReceive(sport.$isFavorite) { _ in self.sports.objectWillChange.send() }
}
}
}.navigationBarTitle("Settings")
}
}
struct ScreenTwo : View{
@ObservedObject var sport : Sport
var body: some View{
NavigationLink(destination: DetailsView(sport: sport)){
Text(sport.isFavorite.description)
}
}
}
struct DetailsView: View {
@ObservedObject 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 {
TestingObservedObject()
}
}
#endif
答案 1 :(得分:0)
@EnvironmentObject -父视图或祖先视图提供的可观察对象的属性包装器类型。
environmentObject(_:)-向视图子层次提供ObservableObject。(这是viewModifire)
以便我们可以通过environmentObject(_:)
共享@ObservableObject。要接受它,子视图应该具有@EnvironmentObject
( ex:-@EnvironmentObject var viewModel:MyViewModel )
答案 2 :(得分:-1)
您应该在ScreenTwo和DetailsView上将运动场定义为@EnviromentObject而不是@ObservedObject。还要在TestingObservedObject视图上通过NavigationLink(destination:ScreenTwo())。environmentObject(sport)设置环境对象。