本文我们将讨论SwiftUI中的另一个出色工具。alignment guide是一种可以用来与SwiftUI的布局系统对话的方法。通过使用对齐指南,我们可以轻松对齐生活在视图层次结构不同部分中的视图。

基础

SwiftUI为我们提供了一些容器视图,可用于构建布局。您可能已经熟悉VStack,HStack和ZStack。所有这些容器视图都使用对齐方式来调整子视图在容器内的位置。让我们看一个非常基本的例子。

VStack(alignment: .leading) {
    Text("Toronto")
    Text("Paris")
    Text("London")
    Text("Madrid")
}



swiftUI 全局loading swiftui padding_子视图


image.png


在上面的示例中,我们有一个垂直容器视图,从上到下显示子视图。我们将对齐方式设置为leading,这意味着VStack将使用每个子视图的leading来对齐它们。

VStack使用HorizontalAlignment枚举定义可能的对齐方式。另一方面,HStack使用VerticalAlignment枚举。这可能很奇怪,但毕竟是合乎逻辑的。由于容器视图控制垂直方向,因此我们只能以水平方式设置VStack的对齐方式。 ZStack使用Alignment枚举,它是HorizontalAlignment和VerticalAlignment枚举的组合.

Overriding alignment guides

SwiftUI允许我们使用alignmentGuide修饰符覆盖标准对齐方式。例如,我们可能需要在水平堆栈中对齐“图像”和“文本”视图的底部。当图像在位图内有一定间距并且看起来不太对齐时,我们可能会遇到问题。这是覆盖对齐指南的理想情况。

struct ContentView: View {
    var body: some View {
        HStack(alignment: .bottom) {
            Image(systemName: "zzz")
                .alignmentGuide(.bottom) { d in d[.bottom] + 8 }
            Text("Sleep")
        }
    }
}



swiftUI 全局loading swiftui padding_子视图_02


image.png


如您在上面的示例中看到的,我们使用alignmentGuide修饰符通过添加8个点来覆盖.bottom对齐的默认值。我们使用d的下标读取默认值,d是ViewDimensions结构的一个实例。 ViewDimensions结构体使我们可以使用下标访问视图的宽度和高度以及默认对齐值

自定义 alignment

我们学习了如何在SwiftUI中override default alignments,但是SwiftUI还允许我们创建自定义alignmentGuide,我们可以在容器视图中使用它来对齐其子视图。但是为什么我们可能需要它呢?自定义对齐方式使我们可以对齐位于不同容器视图中的视图。让我们看下面的例子。

struct ContentView: View {
    var body: some View {
        HStack(alignment: .center) {
            Image(systemName: "star")
            VStack(alignment: .center) {
                Text("Toronto")
                Text("Paris")
                Text("London")
                Text("Madrid")
            }
        }
    }
}



swiftUI 全局loading swiftui padding_swiftUI 全局loading_03


image.png


我们有一个包含图像的水平堆栈和一个带有一些文本视图的垂直堆栈。我可能需要将图像与第三个文本视图对齐,但是在当前配置下看起来不可行,因为这些视图位于不同的容器中。幸运的是,SwiftUI允许我们创建自定义对齐方式,并在父容器视图中使用它。

extension VerticalAlignment {
    struct CustomAlignment: AlignmentID {
        static func defaultValue(in context: ViewDimensions) -> CGFloat {
            return context[VerticalAlignment.center]
        }
    }

    static let custom = VerticalAlignment(CustomAlignment.self)
}

struct ContentView: View {
    var body: some View {
        HStack(alignment: .custom) {
            Image(systemName: "star")
            VStack(alignment: .leading) {
                Text("Toronto")
                Text("Paris")
                Text("London")
                    .alignmentGuide(.custom) { $0[VerticalAlignment.center] }
                Text("Madrid")
            }
        }
    }
}



swiftUI 全局loading swiftui padding_swiftUI 全局loading_04


image.png


在上面的示例中,我们使用AlignmentID协议创建自定义对齐方式。该协议具有我们需要提供的唯一要求。每当我们不使用自定义值时,SwiftUI都会使用defaultValue。有趣的事实是内部VStack并未为自定义对齐指定值,而是使用提供其子视图的值。

结论
今天,我们了解了SwiftUI中自定义对齐的强大功能。我们还可以使用优先对齐技术来构建超级自定义布局。例如,我们可以构建一个grid视图,该grid视图的子视图通过alignment排列。