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 可以自定义对齐点,实现更精细的控制。

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

发表回复

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