[SwiftUI 知识碎片] Debris-9 SwiftUI 主视图的背后藏着什么?

387 阅读2分钟
更多内容欢迎关注公众号:Swift花园

当我们最开始尝试 SwiftUI 的时候,对这段代码一定不陌生:

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}

像下面这样给这个文本视图加一个背景色,然后期望这个颜色填满这个屏幕。我相信一定有人这么干过:

struct ContentView: View {
    var body: some View {
        Text("Hello World")
            .background(Color.red)
    }
}

不过,预期落空。实际上,我们会得到一个在屏幕中央占据一小块的红色文本视图,背后是一整片白色的海洋。

这个现象一定会令大家困惑,并且产生一个疑问 —— “怎样才能让这个 Hello World 背后整个屏幕的区域都变成红色呢?”

让我来划一下重点:记住, SwiftUI 开发者来说,我们的视图背后,什么也没有。 是的,它就是字面上的含义,你不应该试图通过奇怪的技巧或者其他后门来实现把屏幕变成红色的操作,换句话说,不要想通过 SwiftUI 之外的方式来达到这个目的。因为,一旦你真正理解了前面那句话,你会知道该怎么做。

其实,目前为止,我们的内容视图背后,至少有一样东西,它叫UIHostingController:它是 UIKit (Apple 原生的 iOS UI 框架) 和 SwiftUI 之间的桥梁。不过,假如你尝试改动这里的话,你很快会发现你的代码之后将无法运行在 Apple 其他的平台上,实际上就是在 iOS 平台上将来也可能停止工作。

回到那个认知,视图背后什么也没有。这是我们所知道的一切。

一旦你领会了这一点,你会意识到正解是让文本视图占据更多的空间 —— 让它填满整个屏幕,而不是精确匹配文本内容。我们可以通过 frame() 修改器来实现者一点,对最大宽和最大高都传入 .infinity

Text("Hello World")
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color.red)

使用 maxWidthmaxHeight 不同于 widthheight —— 我们并不是在要求文本视图一定要占满空间,而是在它可以的前提下。如果周围有其他的视图,SwiftUI 会确保大家都得到足够的空间。

默认情况下,你的视图不会脱离安全区域。不过你可以用 edgesIgnoringSafeArea() 修改器改变这一点:

Text("Hello World")
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color.red)
    .edgesIgnoringSafeArea(.all)


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~