简体   繁体   中英

Swift binding to a computed property

Have the following situation. I have a view model that is an observable object with a computed property of type Bool. I want to be able to enable/disable a navigation link based on the computed property, but I need a binding to do so. Here a simplified example:

struct Project {
    var name: String
    var duration: Int
}

class MyViewModel: Observable Object {
    @Published var project: Project

    var isProjectValid: Bool {
        return project.name != "" && project.duration > 0
    }
}

struct MyView: View {
    @EnvironmentObject var myVM: MyViewModel

    var body: some View {
        ...
        NavigationLink("Click Link", isActive: ?????, destination: NextView())
        ...
    }
}

Since isActive expects a binding I am not able to access computed property such as myVM.isProjectValid. Tried also with the computed property in project class, still same problem.

Also considered creating custom binding related to the computed property, but not quite sure if/how to go about it.

First question I have posted, so if I am missing some details please be kind:)

Make it a @Published property and update it when project is changed

class MyViewModel: ObservableObject {
    @Published var project: Project {
        didSet {
            isProjectValid = project.name != "" && project.duration > 0
        }
    }

    @Published var isProjectValid: Bool

     //...
}

The use of the computed property suggests some type of design where the user is not supposed to trigger the NavigationLink directly. But instead the NavigationLink is expected to be triggered programatically as a side-effect of some other mechanism elsewhere in the code. Such as might be done at the completion of a form or similar process by the user.

Not 100% if this is what's being aimed for, but if it is, then one option would be to pass a constant Binding to the NavigationLink , eg

NavigationLink("Click Link", isActive: .constant(myVM.isProjectValid), destination: NextView())`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM