SwiftUI自定义对齐方式
SwiftUI自定义对齐方式

SwiftUI自定义对齐方式

实现需求

在SwiftUI视图中,上面是两组元素:

struct ContentView: View {
    var body: some View {
        HStack() { // 使用自定义对齐方式
            VStack {
                Text("WebSite")
                Image(systemName: "globe")
                    .font(.system(size: 100))
            }

            VStack {
                Text("https:")
                Text("fangjunyu.com")
                    .font(.largeTitle)
            }
        }
    }
}

在 SwiftUI 中,HStack 和 VStack 支持对齐选项,比如 .top、.bottom、.center 等。但是,当多个视图分布在不同容器(如 VStack 中)时,无法直接对齐它们的特定位置。此时,需要定义自定义的对齐方式

在这一场景中,因为两组元素在同一个HStack中,但他们又在不同的VStack中。所以,如果想要 Text(“webSize”) Text(“fangjunyu.com”) 对齐的话,就需要定义一个自定义的对齐方式,确保两个元素按照统一基准对齐。

自定义对齐方式

1、对齐方式和 AlignmentID 协议

SwiftUI 提供了一种机制来创建自定义的对齐方式:

VerticalAlignment:定义垂直方向上的对齐。

AlignmentID 协议:用于指定视图的对齐点。

通过扩展 VerticalAlignment 并遵守 AlignmentID 协议,可以创建一个自定义的对齐点。

2、定义自定义的垂直对齐

先创建一个自定义的对齐方式,命名为 midWebName。

import SwiftUI

// 扩展 VerticalAlignment,添加自定义对齐方式
extension VerticalAlignment {
    // 定义一个结构体或枚举,用来标识对齐点
    struct MidWebName: AlignmentID {
        // 提供一个默认值(当视图未指定对齐点时使用)
        static func defaultValue(in context: ViewDimensions) -> CGFloat {
            context[.top] // 默认使用视图的顶部对齐
        }
    }

    // 创建一个静态属性,用于方便引用
    static let midWebName = VerticalAlignment(MidWebName.self)
}

代码解释

1、扩展 VerticalAlignment

通过扩展 VerticalAlignment 来创建新的对齐方式。

2、定义 MidWebName 结构体

这个结构体遵守 AlignmentID 协议。

defaultValue 方法:用于提供默认的对齐点,这里设置为视图的顶部(context[.top])。

3、静态属性 midWebName

通过 VerticalAlignment 构造函数,将 MidWebName 类型作为参数,创建一个新的对齐方式。

3、使用自定义的对齐方式

现在,可以将 midWebName 用在布局中,确保两个不同容器中的元素对齐到一个统一的基准点。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(alignment: .midWebName) { // 使用自定义对齐方式
            VStack {
                Text("WebSite")
                    .alignmentGuide(.midWebName) { d in d[VerticalAlignment.center] }
                Image(systemName: "globe")
                    .font(.system(size: 100))
            }

            VStack {
                Text("https:")
                Text("fangjunyu.com")
                    .alignmentGuide(.midWebName) { d in d[VerticalAlignment.center] }
                    .font(.largeTitle)
            }
        }
    }
}

代码解析

1、HStack(alignment: .midWebName)

将 HStack 的垂直对齐方式设置为自定义的 midWebName。

2、.alignmentGuide(.midWebName)

为需要对齐的视图(WebSite和 fangjunyu.com)指定一个对齐参考点。

使用 d[VerticalAlignment.center]:让视图的中心作为对齐点。

3、结果

即使这两个文本在不同的 VStack 中,它们的中心也会按照 midWebName 这个自定义基准点对齐。

4、运行结果

视图将按照以下规则排列:

左侧的 WebSite 和右侧的 fangjunyu.com,它们的中心位置会垂直对齐。

即使在各自的 VStack 中增加其他内容,这两个元素仍然保持居中对齐。

总结

自定义对齐步骤

1、扩展 VerticalAlignment。

2、定义一个遵守 AlignmentID 协议的结构体或枚举。

提供一个默认对齐点(如 context[.top])。

3、创建一个静态属性,方便引用。

4、在容器中设置自定义对齐方式,使用 .alignmentGuide() 设定视图的对齐基准。

参考文章

1、How to create a custom alignment guide:https://www.hackingwithswift.com/books/ios-swiftui/how-to-create-a-custom-alignment-guide

2、SwiftUI常用的对齐方式:https://fangjunyu.com/2024/12/17/swiftui%e5%b8%b8%e7%94%a8%e7%9a%84%e5%af%b9%e9%bd%90%e6%96%b9%e5%bc%8f/

扩展知识

VerticalAlignment 和 VStack 的关系

在 SwiftUI 中,VStack 用于垂直排列子视图,并且允许通过 alignment 参数设置视图的对齐方式。

VerticalAlignment 就是 SwiftUI 提供的一组垂直对齐选项,用来定义子视图在 VStack 中如何对齐。

VStack 的 alignment 参数:

用于指定所有子视图的对齐基准,例如 .leading、.center、.trailing。

VStack(alignment: .leading) {
    Text("Hello")
    Text("SwiftUI")
}

在上面的代码中,所有视图会向 leading(左侧)对齐。

VerticalAlignment

是一个枚举,包含内置的垂直对齐选项,同时允许用户扩展自定义对齐方式。

内置的对齐方式:.top、.center、.bottom

自定义对齐方式:通过扩展 VerticalAlignment 创建新的对齐点。

AlignmentID 协议是什么?

AlignmentID 是 SwiftUI 中的一个协议,主要用于创建自定义对齐基准。通过实现 AlignmentID,可以定义新的对齐方式,并精确控制视图的对齐点。

AlignmentID 的要求

必须提供一个 defaultValue 静态方法。

该方法返回一个 CGFloat,表示当视图没有明确的对齐点时,应该使用的默认值。

参数 ViewDimensions 提供了视图的布局信息,例如 .top、.bottom、.leading 等位置的值。

为什么需要 AlignmentID?

SwiftUI 内置的对齐方式(如 .top、.bottom)不能满足所有对齐需求,比如让两个不同 VStack 中的视图按一个特定基准点对齐。AlignmentID 可以自定义对齐点,实现更精细的控制。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注