如何基于可选对象使SwiftUI NavigationLink有条件?

如何基于可选对象使SwiftUI NavigationLink有条件?,swiftui,swiftui-navigationlink,observableobject,Swiftui,Swiftui Navigationlink,Observableobject,假设我有一个模型类Ball,它符合observateObject协议,我定义了它的一个可选实例(var Ball:Ball?) 是否有方法触发导航链接,根据可选实例的值显示其目的地视图?所以当我self.ball=ball()时,会触发NavigationLink 一个问题似乎是可选(类型?)不能是@ObservedObject 另一个问题似乎是是活动的:导航链接的参数只能进行绑定 ///设计了一个简单的例子来说明这个问题。 包括SwiftUI 类球:ObservieObject{ @已发布变量

假设我有一个模型类
Ball
,它符合
observateObject
协议,我定义了它的一个可选实例(
var Ball:Ball?

是否有方法触发
导航链接
,根据可选实例的值显示其
目的地
视图?所以当我
self.ball=ball()
时,会触发
NavigationLink

一个问题似乎是可选(
类型?
)不能是
@ObservedObject

另一个问题似乎是
是活动的:
导航链接的参数只能进行
绑定

///设计了一个简单的例子来说明这个问题。
包括SwiftUI
类球:ObservieObject{
@已发布变量颜色:String=“红色”
// ...
}
结构ContentView:View{
//设置时不会触发视图更新,因为未观察到:
球:球?
//这一行不会编译:
@ObservedObject变量observedBall:球?

//到目前为止,我对上述限制的最佳解决方案包括:

  • 将另一个符合ObserveObject的类定义为可选Ball实例的包装器
  • @State var ballIsSet=false
    (或
    @Binding var ballIsSet:Bool
    )变量添加到我的视图中
  • 将ballIsSet布尔变量传递给包装类对象
  • 然后在wrapped Ball变量上使用
    didSet
    函数更新传入的布尔值

希望有人知道一种更简单/更好的方法

//这仍然是一个有点做作的例子,但它说明了一些要点…
类ObservableBall:ObservableObject{
//设置ball变量时要调用的闭包
私有变量whenSetClosure:((Bool)->无效)?
@球:球{
迪塞特{
//如果指定了闭包,则在球设定时调用它
如果let setClosure=self.whenSetClosure{
setClosure(self.ball!=nil)
}
}
}
初始值(u-ball:ball?=nil,当阈值:((Bool)->Void)?=nil){
self.ball=球
self.whenSetClosure=whenSetClosure
}
}
结构ContentView:View{
@ObservedObject变量observedBall=ObservableBall()
@状态变量ballIsSet=false
var body:一些观点{
导航视图{
VStack{
//当ballIsSet变为true时,导航到ballView:
导航链接(
//我们可以强行打开观察到的球。球!这里
//因为只有当ballIsSet为true时才会调用:
目的地:BallView(球:self.observedBall.ball!),
isActive:$ballIsSet
) {
EmptyView()
}
//按钮用户点击设置“球”,
//触发要显示的球视图。
钮扣(
操作:{self.observedBall.ball=ball()},
标签:{Text(“Show Ball”)}
)
}
奥纳佩尔先生{
observedBall.whenSetClosure={isSet-in
self.ballIsSet=isSet
}
}
}
}
}

到目前为止,我对上述限制的最佳解决方案包括:

  • 将另一个符合ObserveObject的类定义为可选Ball实例的包装器
  • @State var ballIsSet=false
    (或
    @Binding var ballIsSet:Bool
    )变量添加到我的视图中
  • 将ballIsSet布尔变量传递给包装类对象
  • 然后在wrapped Ball变量上使用
    didSet
    函数更新传入的布尔值

希望有人知道一种更简单/更好的方法

//这仍然是一个有点做作的例子,但它说明了一些要点…
类ObservableBall:ObservableObject{
//设置ball变量时要调用的闭包
私有变量whenSetClosure:((Bool)->无效)?
@球:球{
迪塞特{
//如果指定了闭包,则在球设定时调用它
如果let setClosure=self.whenSetClosure{
setClosure(self.ball!=nil)
}
}
}
初始值(u-ball:ball?=nil,当阈值:((Bool)->Void)?=nil){
self.ball=球
self.whenSetClosure=whenSetClosure
}
}
结构ContentView:View{
@ObservedObject变量observedBall=ObservableBall()
@状态变量ballIsSet=false
var body:一些观点{
导航视图{
VStack{
//当ballIsSet变为true时,导航到ballView:
导航链接(
//我们可以强行打开观察到的球。球!这里
//因为只有当ballIsSet为true时才会调用:
目的地:BallView(球:self.observedBall.ball!),
isActive:$ballIsSet
) {
EmptyView()
}
//按钮用户点击设置“球”,
//触发要显示的球视图。
钮扣(
操作:{self.observedBall.ball=ball()},
标签:{Text(“Show Ball”)}
)
}
奥纳佩尔先生{
observedBall.whenSetClosure={isSet-in
self.ballIsSet=isSet
}
}
}
}
}
这里是另一个(更简单的)变体-使用状态作为属性,使用常量绑定作为条件

struct ContentView: View {

  @State private var ball: Ball?       // << state to be modifiable

  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(
          destination: BallView(ball: self.ball), 
          isActive: .constant(self.ball != nil)   // << activate conditionally
        ) {
          EmptyView()
        }

        Button(action: { self.ball = Ball() }, label: { Text("Show Ball") })
      }
    }
  }
}
struct ContentView:View{
@State-private-var-ball:ball?/这里是另一个(更简单的)变量-使用State作为属性,使用常量绑定作为条件

struct ContentView: View {

  @State private var ball: Ball?       // << state to be modifiable

  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(
          destination: BallView(ball: self.ball), 
          isActive: .constant(self.ball != nil)   // << activate conditionally
        ) {
          EmptyView()
        }

        Button(action: { self.ball = Ball() }, label: { Text("Show Ball") })
      }
    }
  }
}
struct ContentView:View{
@国家私人舞会:舞会//