SwiftUI 学习(四)

342 阅读4分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

VStack, HStack

Stacks——相当于 UIKit 中的 UIStackView——有三种形式:水平(HStack)、垂直(VStack)和基于深度的(ZStack, 子视图以使它们重叠时使用)。

VStack {
    Text("VStack0")
    Text("VStack1")
}

HStack {
    Text("HStack0")
    Text("HStack1")
}

VStack, HStack 布局

可以通过在初始化Stack中提供一个值来添加间距,如下所示:

VStack(spacing: 50) {
    Text("VStack0")
    Text("VStack1")
    Text("VStack2")
}

或者,可以在每个Item之间创建分隔线,以便Stack中的每个item之间进行小的视觉区分,如下所示:

VStack {
    Text("VStack0")
    Divider()
    Text("VStack1")
    Text("VStack2")
}

默认情况下,Stack中的item居中对齐。 在 HStack 的情况下,这意味着item在中间垂直对齐,所以如果有两个不同高度的文本视图,它们都将对齐到它们的垂直中心。 对于 VStack ,这意味着item在中间水平对齐,因此如果您有两个不同长度的文本视图,它们都将对齐到它们的水平中心。

要对此进行调整,请在创建Stack时传入alignment,如下所示:

VStack(alignment: .leading) {
    Text("xxx VStack0")
    Divider()
    Text("VStack1 yy")
    Text("h")
}

使用Spacer

默认情况下,SwiftUI 将其视图居中,这意味着如果您将三个文本视图放置在 VStack 中,所有三个文本视图都将在屏幕中垂直居中。 如果你想改变这一点——如果你想强制视图朝向屏幕的顶部、底部、左侧或右侧——那么你应该使用 Spacer 。

VStack {
    Text("Hello World")
    Spacer()
}

image.png

如果你想在 HStack 的前缘和后缘上放置两条文本,你可以使用这样的分隔符:

HStack {
    Text("Hello")
    Spacer()
    Text("World")
}

image.png

SwiftUI 的 Spacer 会自动填充其扩展轴上的所有可用空间,这是一种奇特的说法,它们在水平或垂直方向上占据尽可能多的空间,具体取决于放入的内容。

如果您想Spacer固定大小,只需对任何其他类型的视图执行相同的操作:添加frame修饰符

VStack {
    Text("First Label")
    Spacer()
        .frame(height: 50)
    Text("Second Label")
}

如果给Spacer一个值范围,例如使用 .frame(minHeight: 50, maxHeight: 500),那么它将自动占用尽可能多的空间,直到您设置的最大值。 以这种方式增加一些灵活性通常是一个好主意,这样您的用户界面就可以更轻松地跨设备扩展。

在某些情况下,希望指定与其布局方向无关的间隔大小,例如,如果您的视图有时可能位于 HStack 或 VStack 中,并且您希望无论方向如何,间隔都添加 50 个点。

在这种情况下,您应该使用 minLength 初始化程序,如下所示:

VStack {
    Text("First Label")
    Spacer(minLength: 50)
    Text("Second Label")
}

使用 ZStack 将视图分层

SwiftUI 具有用于创建重叠内容的专用堆栈类型,例如,如果您想在图片上放置一些文本,这很有用。 它被称为 ZStack,它的工作方式与其他两种堆栈类型相同。

ZStack {
    Image("niagara-falls")
    Text("Hacking with Swift")
        .font(.largeTitle)
        .background(Color.black)
        .foregroundColor(.white)
}

image.png

默认情况下,SwiftUI 的 ZStack 使用 Painter 算法来决定视图的深度:首先将您放入 ZStack 中的任何内容都先绘制,然后将后续视图分层。虽然这通常是您想要的,但有时您需要更多控制权——例如,您可能希望在应用程序运行时将一个视图推到另一个视图之后,或者在点击某个特定视图时将其置于前面。

为此,您需要使用 zIndex() 修饰符,它允许您准确指定视图应如何在单个 ZStack 中分层。 视图的默认 Z 索引为 0,但您可以提供正值或负值,分别将它们定位在其他视图的顶部或下方。

例如,这个 ZStack 包含两个重叠的矩形,但绿色矩形仍然可见,因为它使用的 Z 索引值为 1:

ZStack {
    Rectangle()
        .fill(Color.green)
        .frame(width: 50, height: 50)
        .zIndex(1)

    Rectangle()
        .fill(Color.red)
        .frame(width: 100, height: 100)
}

image.png