如何使SwiftUI视图全屏显示?

24

如标题所述,我正在尝试将视图全屏(使其覆盖 SafeArea),但是 SwiftUI 似乎总是将视图对齐到 safeArea

经过一番研究,我找到了 .edgesIgnoringSafeArea(.all) 这个方法,它看起来是一个非常直接的方法。问题在于它并不起作用。视图仍然没有全屏显示。这里是一些示例代码:

struct ContentView : View {
    var body: some View {
        Text("Test")
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .edgesIgnoringSafeArea(.all)
            .background(Color.red)
    }
}

我认为edgesIgnoringSafeArea所做的一切就是将视图内容居中,忽略安全区域。你真正需要考虑的问题是 - 为什么要忽略安全区域?苹果公司几年来一直在引导开发人员尊重安全区域 - 实际上,我相信他们很快(如果还没有)会将其作为拒绝的理由。在UIKit中有一种方法可以“忽略”安全区域...隐藏状态栏。也许可以在SwiftUI中找到一种方法来实现这一点。 - user7014451
1
谢谢您的评论。隐藏状态栏确实起作用了,谢谢,但我想继续寻找一种不必隐藏状态栏的解决方案。我想忽略它的原因是我想在顶部显示一个MKMapView,它也应该在缺口后面(就像在Apple Maps应用程序中一样)。这只是为了外观而已。 - timfraedrich
2
@dfd 忽略安全区域有很多原因;例如,您可能想为视图提供自定义背景。如果您的背景图片在顶部和底部有白色条纹,那么它看起来会非常丑陋。但是您不应该将用户直接交互的UI元素(如按钮)放入安全区域。 - Peter Schorn
4个回答

42

只需交换..background(Color.red)和.edgesIgnoringSafeArea(.all)的位置,就可以完美地解决问题。

struct ContentView : View {

    var body: some View {
        Text("Test")
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.red)
            .edgesIgnoringSafeArea(.all)

    }
}

3
很奇怪,我之前已经尝试过了,但现在它似乎可以工作了。也许这只是测试版中的一个小故障。无论如何,还是谢谢你。 - timfraedrich
1
这是一个错误还是它应该这样工作的? - Sulthan
1
也许这是一个 bug,也许不是。我不能确定。但我发现如果在 Text("Test") 后面设置背景颜色,它只会给字符串 "Test" 所占据的内容框架着色。但如果在设置框架后再设置背景颜色,则会给整个框架着色。 - Md Shafiul Islam
1
我认为这是一个bug... .edgesIgnoringSafeArea(.all) 应该修改视图的大小,而 .background(Color.red) 应该修改视图的背景颜色。但实际上,似乎 .background() 也在修改大小。 - mbxDev
5
这不是一个错误,它可以让你更加灵活地控制想要发生的事情,但在某种程度上会相当混乱和尴尬。基本上,在任何后续修改器调整视图大小之前,颜色应用于视图本身。先应用颜色,然后再添加像填充这样的内容,额外的填充部分不会被着色。先添加填充,再进行着色,整个视图都会被着色。 - CMash
1
它的行为就像有几层视图一样,在填充后创建一个新视图。这是真的吗?请考虑以下内容:var body: some View { Text("测试") .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity) .edgesIgnoringSafeArea(.all) .background(Color.red) .padding(25) .background(Color.blue) }。这将给出一个带有蓝色边框的红色内容,而不是完全的蓝色。 - claude31

7

根据苹果iOS 14 文档,您可以使用fullScreenCover(item:onDismiss:content:)方法。

以下是示例代码:

struct ContentView: View {
    @State private var isFullScreen = false
    var body: some View {
        ZStack{
        Color.yellow.edgesIgnoringSafeArea(.all)
        Text("Hello, FullScreen!")
            .padding()
            .background(Color.blue)
            .foregroundColor(.green)
            .cornerRadius(8)
            .fullScreenCover(isPresented: $isFullScreen) {
                FullScreen(isFullScreen: $isFullScreen)
            }
            .onTapGesture {
                isFullScreen.toggle()
            }
    }
    }
}

struct FullScreen: View {
    @Binding var isFullScreen: Bool
    
    var body: some View {
        ZStack {
            Color.red.edgesIgnoringSafeArea(.all)
            Text("This is full screen!!")
                .onTapGesture {
                    self.isFullScreen.toggle()
                }
            
        }
    }
}

2
虽然这并不是针对全尺寸表格的解决方案,但它是针对基本用例的非常好的解决方案。非常感谢,我很欣赏你的代码片段。 - LukeSideWalker

5

在SwiftUI中使用增强现实应用程序也存在全屏输入问题。(Xcode 12.3,SwiftUI 5.3)

struct ContentView : View {
    var body: some View {
        return ARViewContainer().edgesIgnoringSafeArea(.all)
    }
}

上面的代码来自AR模板,但它无法工作。
解决方法有些棘手:您需要在“[yourTarget] -> General -> App Icons and Launch Images”中将“LaunchScreen.storyboard”设置为“Launch Screen File”。如果项目中没有“LaunchScreen.storyboard”,仍然可以通过在该字段中输入“LaunchScreen”来工作。
我在苹果论坛上发现了一个类似的讨论,解释了可能失败的潜在原因:

如果没有正确设置,那么您的应用程序似乎正在启动到兼容模式,这会使您的应用程序出现黑边。


2
我曾经遇到同样的问题,但我正在使用SwiftUI和SpriteKit。由于某种原因,它无法进入全屏模式。尽管我没有启动画面文件,但我尝试了这个解决方法,它成功了。我抓破头花了几个小时来解决这个问题。不过现在很高兴它已经可以工作了。 - James Castrejon

0
ZStack {
                    Text("Test")
                    Rectangle()
                        .fill(.clear)
                        .background(Color.clear)
                        .edgesIgnoringSafeArea(.all)
                        .contentShape(Rectangle())
                        .onTapGesture {
                            //tap action
                        }
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接