如何使 SwiftUI .sheet() 大小与 MacOS 上窗口的宽度/高度相匹配?

tyl*_*rva 7 swiftui

背景

我正在 Catalina 上的 Xcode 12.4 中的 SwiftUI 中开发 MacOS 应用程序。现在,我的应用程序有一个带有图块的登陆页面,每个图块都包含一个使用工作表显示的功能。

ForEach(MenuItem.allCases) { menuItem in
    Button(action: {
        detailView = menuItem
    }) {
        Tile(labelText: menuItem.menuText, icon: menuItem.menuIcon)
            .sheet(item: $detailView) { item in
                FeatureView(dismissFeatureView: { self.detailView = nil }, menuItem: item)
                    .environmentObject(container)
                    .background(Color("backgroundMain"))
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

窗口具有最小宽度和高度,但由于没有最大高度或宽度,因此可以扩展。我正在寻找一种方法使工作表占据整个屏幕。在 iOS 上您可以使用.fullScreenCover(),但在 MacOS 上不可用。所以现在,当我放大屏幕并单击图块时,工作表视图不会占用整个空间

此外,用户还可以将工作表的大小调整到超出窗口的大小,如此处所示

问题

如何使工作表视图与窗口的大小(没有最大宽度或高度)相匹配,以便用户仍然可以调整窗口大小,但确保工作表始终占据整个窗口。

And*_*Ley 5

如果您在用户交互后显示工作表,则可以按如下方式设置工作表内容的框架:

.frame(idealWidth: NSApp.keyWindow?.contentView?.bounds.width ?? 500, idealHeight: NSApp.keyWindow?.contentView?.bounds.height ?? 500)
Run Code Online (Sandbox Code Playgroud)

巧妙的部分是,这可以由不了解其超级视图的嵌套控件使用。

500keyWindow如果找不到a ,则用作后备宽度/高度。

请记住:工作表可能高于其内容框架的高度,因为它可能包含其他控件(例如工具栏)。


tyl*_*rva 0

一种解决方案是使用GeometryReader获取父视图的大小,并将其应用于工作表的框架。参见下面的代码:

GeometryReader { geometry in
    VStack(alignment: .center) {
        HStack(alignment: .center, spacing: 20) {
            ForEach(MenuItem.allCases) { menuItem in
                Button(action: {
                    detailView = menuItem
                }) {
                    Tile(labelText: menuItem.menuText, icon: menuItem.menuIcon)
                        .sheet(item: $detailView) { item in
                            FeatureView(dismissFeatureView: { self.detailView = nil }, menuItem: item)
                                .environmentObject(container)
                                .background(Color("backgroundMain"))
                                .frame(width: geometry.size.width, height: geometry.size.height)
                        }

                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)