绑定到 SwiftData @Query 数组中第一个元素的属性

问题描述 投票:0回答:1

我有一个 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()
})
swiftui binding swift-data
1个回答
0
投票

您可以尝试这种简单的方法,使用额外的

@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
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.