前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SwiftUI 布局:如何自定义 AlignmentGuides

SwiftUI 布局:如何自定义 AlignmentGuides

作者头像
Swift社区
发布2021-11-26 13:10:48
9900
发布2021-11-26 13:10:48
举报
文章被收录于专栏:Swift社区

SwiftUI 为我们提供了视图不同边缘的对齐指南(.leading、trailing、top等)以及.center和两个基线选项来帮助文本对齐。

然而,当您处理在不同视图之间分割的视图时,这些方法都不能很好地工作——如果您必须使在用户界面完全不同的两个视图部分对齐。

为了解决这个问题,SwiftUI 允许我们创建自定义的对齐辅助线,并在整个 UI 的视图中使用这些辅助线。在这些视图之前或之后发生什么并不重要,它们仍然会排成一条线。

例如,下面的布局在左侧显示我的 Twitter 帐户名和我的个人资料图片,右侧显示 “Full name:” 加上 “Wei Xian” 的大号字体:

代码语言:javascript
复制
struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Text("@twostraws")
                Image("wei-xian")
                    .resizable()
                    .frame(width: 64, height: 64)
            }

            VStack {
                Text("Full name:")
                Text("WEI XIAN")
                    .font(.largeTitle)
            }
        }
    }
}

如果你想让 “@twostraws” 和 “Wei Xian” 垂直对齐,你现在就很难了。水平堆栈内部包含两个垂直堆栈,因此没有内置的方法来获得所需的对齐方式——像HStack(alignment: .top) 这样的方便的方式。

要解决这个问题,我们需要定义一个自定义布局指南。这应该是VerticalAlignment或HorizontalAlignment的扩展,并且是符合AlignmentID协议的自定义类型。

当我说“自定义类型”时,您可能会想到一个结构体,但实际上,将其作为枚举来实现是一个好主意,我将很快解释。

AlignmentID协议只有一个要求,即一致性类型必须提供一个静态defaultValue(in:)方法,该方法接受ViewDimensions对象并返回一个CGFloat,指定如果视图没有alignmentGuide()修饰符,该视图应该如何对齐。您将获得视图的现有ViewDimensions对象,因此您可以选择其中一个作为默认值,也可以使用硬编码值。

让我们写出代码,这样您就可以看到它的样子:

代码语言:javascript
复制
extension VerticalAlignment {
    struct MidAccountAndName: AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            d[.top]
        }
    }

    static let midAccountAndName = VerticalAlignment(MidAccountAndName.self)
}

您可以看到我在默认情况下使用了.top视图维度,并且还创建了一个名为midAccountAndName的静态常量,以使自定义对齐更易于使用。

现在,我提到使用枚举比使用结构体更可取,原因如下:

我们刚刚创建了一个名为MidAccountAndName的新结构体,这意味着我们可以(如果需要的话)创建该结构体的实例,即使这样做没有任何意义,因为它没有任何功能。如果将struct MidAccountAndName替换为enum MidAccountAndName,那么就不能再创建它的一个实例了——它的存在只是为了容纳一些功能。

无论您选择的是枚举还是结构体,其用法都保持不变:将其设置为堆栈的对齐方式,然后使用alignmentGuide()在要对齐的任何视图上激活它。这只是一个指南:它帮助您沿一条直线对齐视图,但没有说明如何对齐视图。这意味着您仍然需要为alignmentGuide()提供闭包,该闭包可以根据需要定位视图。

例如,我们可以将 Twitter 代码更新为use.midAccountAndName,然后告诉帐户和名称使用其中心位置作为指南。明确地说,这意味着“对齐这两个视图,使它们的中心都位于.midAccountAndName指南上”。

下面是代码:

代码语言:javascript
复制
HStack(alignment: .midAccountAndName) {
    VStack {
        Text("@twostraws")
            .alignmentGuide(.midAccountAndName) { d in d[VerticalAlignment.center] }
        Image("paul-hudson")
            .resizable()
            .frame(width: 64, height: 64)
    }

    VStack {
        Text("Full name:")
        Text("PAUL HUDSON")
            .alignmentGuide(.midAccountAndName) { d in d[VerticalAlignment.center] }
            .font(.largeTitle)
    }
}

这将确保它们是垂直对齐的,不管前面或后面是什么。我建议您尝试在我们的示例前后添加更多的文本视图 –SwiftUI 将重新定位所有内容,以确保我们对齐的两个视图保持不变。

译自 How to create a custom alignment guide

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Swift社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档