我有一个 SwiftData 模型
Player
,数据库中应该只有 0 或 1。当用户位于主菜单并点击“开始新游戏”时,我会引导他们通过几个屏幕来选择游戏选项。选择所有选项后,我将删除所有现有的 Player
对象并插入一个新对象。然后我关闭所有这些选项选择屏幕。
那么我想要的就是自动显示游戏视图。但我不确定如何将
.fullScreenCover()
绑定到 SwiftData Player.isShown
中第一个元素上的 @Query
属性。
下面的代码不起作用,因为:
Cannot convert value of type 'Bool?' to expected argument type 'Binding<Bool>'
我对 Swift 和 SwiftUI 还很陌生,所以我对可绑定和可观察的掌握仍然很薄弱。
struct RootContentView: View {
@Query var activeplayers: [Player] // should only ever be 0 or 1
var body: some View {
ZStack {
// stuff
}
.fullScreenCover(isPresented: activeplayers.first?.isshown content: {
GameView()
})
}
}
如何根据 SwiftData
GameView
中可选的第一个元素自动显示我的 @Query
屏幕?
我还尝试只是查询是否有任何玩家存在于
.isShown == true
,然后绑定到$activeplayers.isEmpty
(这与我真正想要的逻辑相反,但我只是想找到某种方法将数据提炼为一个 bool 属性,我想我可以稍后反转逻辑)但这也不起作用:
@Query (filter: #Predicate<Player> {
$0.isshown == true
}) var activeplayers: [Player]
// ...
// without the $, gives the error:
// Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'
.fullScreenCover(isPresented: activeplayers.isEmpty content: {
GameView()
})
// with the $, gives the error:
// Cannot find '$activeplayers' in scope
.fullScreenCover(isPresented: $activeplayers.isEmpty content: {
GameView()
})
您可以尝试这种简单的方法,使用额外的
@State var shouldShow
并将其设置为.onAppear {...}
,如示例代码所示
struct RootContentView: View {
@Environment(\.modelContext) private var modelContext
@Query var activeplayers: [Player]
@State var shouldShow = false // <-- here
var body: some View {
VStack {
Text("testing")
}
.fullScreenCover(isPresented: $shouldShow) { // <-- here
GameView()
}
// -- here
.onAppear {
if let player = activeplayers.first, let doShow = player.isshown {
shouldShow = doShow
}
}
}
}