Hacking with iOS: SwiftUI Edition

SwiftUI 布局:视图的绝对定位

2020-12-08  本文已影响0人  韦弦Zhy

\color{red}{\Large \mathbf{Hacking \quad with \quad iOS: SwiftUI \quad Edition}}

{\Large \mathbf{Absolute \ Positioning }}

SwiftUI为我们提供了两种定位视图的方法:使用 position() 的绝对位置和使用 offset() 的相对位置。它们看起来可能很相似,但一旦了解了 SwiftUI 如何将视图放置在Frame内,position()offset() 之间的根本区别就变得更清楚了。

默认的 SwiftUI 模板如下所示:

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

SwiftUI为 ContentView 提供了全部可用空间,而 ContentView 又将其传递给文本视图。文本视图自动使用的空间仅限于其文本所需的空间,因此它将这些空间传递回ContentView,后者始终与正文大小完全相同(因此它直接适合于文本)。因此,SwiftUI将ContentView集中在可用空间中,从用户的角度来看,这是将文本放在中心的地方。

如果要绝对定位 SwiftUI 视图,应使用position()修饰符,如下所示:

Text("Hello, world!")
    .position(x: 100, y: 100)

这将把文本视图定位在其父视图中的 x:100 y:100。现在,为了真正了解这里发生了什么,我希望您添加一个背景色:

Text("Hello, world!")
    .background(Color.red)
    .position(x: 100, y: 100)

你会看到文本周围有一个紧密贴合的红色背景。现在尝试将background()修饰符移到 position() 修饰符下方,如下所示:

Text("Hello, world!")
    .position(x: 100, y: 100)    
    .background(Color.red)

现在您将看到文本在同一位置,但整个Safe Area 是红色的。

要了解这里发生了什么,您需要记住SwiftUI的三步布局过程:

  1. 父视图提供一个大小并询问其子视图的大小。
  2. 子视图根据自己的信息,它会选择自己的尺寸,而父视图必须尊重这个选择。
  3. 然后父视图在其坐标空间中定位子视图。

所以,父母负责定位孩子,而不是孩子自己。这导致了一个问题,因为我们刚刚告诉我们的文本视图处于一个准确的位置——SwiftUI如何解决这个问题?

这个问题的答案也是为什么我们的background() 使整个安全区域变为红色:当我们使用position()时,我们会得到一个新的视图,它会占用所有可用的空间,这样它就可以将它的子视图(文本)放在正确的位置。

当我们使用文本、位置和背景时,位置将占用所有可用空间,以便它能够正确地定位其文本,然后背景将为其自身使用该大小。当我们使用文本、背景和位置时,背景将使用文本大小作为其大小,然后位置将占用所有可用空间并将背景放置在正确的位置。

在前面讨论offset()修饰符时,我说“如果偏移一些文本,它的原始尺寸实际上没有改变,即使结果视图是在不同的位置呈现的。”记住这一点,请尝试运行以下代码:

var body: some View {
    Text("Hello, world!")
        .offset(x: 100, y: 100)
        .background(Color.red)
}

你会看到文本出现在一个地方,背景出现在另一个地方。我要解释为什么会这样,但首先我希望你自己考虑一下,因为如果你理解了这一点,那么你就真正理解了SwiftUI的布局系统是如何工作的。

当我们使用offset()修饰符时,我们改变了一个视图应该呈现的位置,而不实际改变它的基本几何体。这意味着当我们随后应用background()时,它使用文本的原始位置,而不是偏移量。如果移动修饰符的顺序,使background()offset()之前,那么事情会更像您预期的那样,再次表明修饰符顺序很重要。

译自 Absolute positioning for SwiftUI views

上一篇下一篇

猜你喜欢

热点阅读