将绑定传递回父级的父级视图

时间:2021-04-14 00:44:19

标签: ios swiftui

我有 4 次观看。

  1. 祖父母
  2. 家长
  3. 孩子
  4. 编辑视图

Grandparent 有一个到 Parent 的导航链接,而 Parent 有一个到 Child 的导航链接。 Child 有一个按钮,它通过 Parent 中的绑定和 Child 中的绑定从祖父母初始化 @State 变量,位置(一个类)。同一个按钮还更新了来自祖父(再次通过绑定)的 @State 变量 showEditView,它显示了 EditView。

目前有 11 行被注释掉。如果它们被注释掉,当我点击子视图中的按钮时,应用程序会抛出“致命错误:意外发现 nil...”错误。如果任一部分未注释,则按钮不会引发错误。

如果我将绑定位置传递给 EditView,而不是像我目前所做的那样将属性本身传递给它,它也可以工作,然后将其包装为 @ObservedObject。

我不明白这里发生了什么。我唯一能想到的是,当它工作时,SwiftUI 正在更新 location 属性,因为它在正文中使用。如果是这种情况,这似乎表明每次我想通过这种方式传递属性时,我都必须包含此属性的隐藏文本视图。

祖父母

import SwiftUI

struct Grandparent: View {
    @State var location: Location!
    @State var showEditView: Bool = false
    
    var body: some View {
        NavigationView {
            VStack{
                NavigationLink(
                    destination: Parent(location: $location, showEditView: $showEditView)) {
                    Text("Navigate")
                }
// //               section 1
//                if location != nil {
//                    Text(location.name)
//                } else {
//                    Text("No location yet")
//                }
            }
// //            section 2
//            .navigationBarItems(trailing:
//                Button("Edit"){
//                    showEditView = true
//                }
//                .disabled(location == nil)
//            )
        }
        .padding()
        .sheet(isPresented: $showEditView) {
            EditView(placemark: location, dismiss: { showEditView = false })
        }
    }
}

家长

import SwiftUI

struct Parent: View {
    @Binding var location: Location!
    @Binding var showEditView: Bool
    
    var body: some View {
        NavigationLink(
            destination: Child(location: $location, showEditView: $showEditView),
            label: {
                Text("Child")
            })
    }
}

孩子

import SwiftUI

struct Child: View {
    @Binding var location: Location!
    @Binding var showEditView: Bool
    var body: some View {
        Button("Make location") {
            location = Location(name: "Lebanon")
            showEditView = true
        }
    }
}

编辑视图

import SwiftUI

struct EditView: View {
    @ObservedObject var placemark: Location
    var dismiss: () -> Void
    
    var body: some View {
        NavigationView {
            Text(placemark.name)
                .navigationTitle("Edit place")
                .navigationBarItems(trailing: Button("Done") { dismiss() })
        }
    }
}

位置

import Foundation

class Location: ObservableObject {
    init(name: String) {
        self.name = name
    }
    
    @Published var name: String
}

1 个答案:

答案 0 :(得分:0)

您可能不应该将您的 Location 声明为 !,然后对其进行 nil 检查。使用 ! 有点像要求发生崩溃。我认为您遇到的是 sheet 在设置 location 之前被渲染。没有关于 when 在运行循环中设置 @State 变量的任何保证,因此最好考虑它为 nil 的情况(并且绝对不使用 { {1}} 强制打开它)。

其次,至少考虑到您在这里的情况,您可能不应该将 ! 用于 class ——它应该只是一个 Location

最终,您会遇到一点复杂性,因为从您的视图名称来看,您希望在某个时候编辑 struct。使用 Location 会变得有点棘手,因为 Optional 之类的东西需要非可选值,但这可以通过各种方式解决(请参阅我使用 TextField 的地方)。

这样的事情绝对比您目前正在做的更安全。它可能不是完全你想要的,但希望它能让你走上正确的道路。

nonNilBinding
相关问题