gpt4 book ai didi

xcode - 将 ObservedObject 传递给嵌套 subview SwiftUI(SwiftUI 数据流)

转载 作者:行者123 更新时间:2023-12-04 15:38:43 26 4
gpt4 key购买 nike

我试图理解为什么传递 @ObservedObject 变量不适用于嵌套 subview 。可以传递数据,但更改仅反射(reflect)在创建 @ObservedObject 变量的 Root View 中。更改不会显示在 subview 中。查看 Apple 文档(已针对 Xcode beta 5 进行了更新),答案似乎是创建环境对象和常规变量,以便从环境对象中获取正确的索引。这是苹果example .

我的理解是,@ObservedObject 可用于从多个 View 引用变量,但如果您希望可以从任何 View 访问数据,那么您应该使用环境对象。因此,我相信通过@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

最佳答案

对于 ObservableObject配对ObservedObject使 View 刷新,因此要解决有问题的任务,我建议采用以下方法:
演示
Usage of ObservingObject/ObjservedObject pattern
代码

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
backup

关于xcode - 将 ObservedObject 传递给嵌套 subview SwiftUI(SwiftUI 数据流),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57551220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com