Swift之深入解析SwiftUI布局如何自定义AlignmentGuides

Posted Forever_wj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift之深入解析SwiftUI布局如何自定义AlignmentGuides相关的知识,希望对你有一定的参考价值。

  • SwiftUI 提供了视图不同边缘的对齐指南(.leading、trailing、top 等)以及 .center 和两个基线选项来帮助文本对齐。然而,当处理在不同视图之间分割的视图时,如果必须使在用户界面完全不同的两个视图部分对齐,这些方法都不能很好地很好解决问题。
  • 为了解决类似的问题,SwiftUI 允许创建自定义的对齐辅助线,并在整个 UI 的视图中使用这些辅助线,在这些视图之前或之后发生什么并不重要,但它们仍然会排成一条线。
  • 例如,下面的布局在左侧显示我的 CSDN 帐户名和我的个人资料头像,右侧显示 “CSDN ID:” 加上 “Forever_wj” 的大号字体:
struct ContentView: View 
    
    var body: some View 
        HStack 
            VStack 
                Text("@CSDN")
                Image("forever_wj")
                    .resizable()
                    .frame(width: 60, height: 60)
            

            VStack 
                Text("CSDN ID:")
                Text("Forever_wj")
                    .font(.title)
            
        
        
    

  • 效果如下:

  • 如果想让 “@CSDN” 和 “Forever_wj” 垂直对齐,那么现在就很难了。水平堆栈内部包含两个垂直堆栈,因此没有内置的方法来获得所需的对齐方式,像 HStack(alignment: .top) 这样的方便的方式。要解决这个问题,我们需要定义一个自定义布局指南,这应该是 VerticalAlignment 或 HorizontalAlignment 的扩展,并且是符合 AlignmentID 协议的自定义类型。
  • 当说到“自定义类型”时,你可能会想到一个结构体,但实际上,我认为将其作为枚举来实现是一个更好的主意。AlignmentID 协议只有一个要求,即一致性类型必须提供一个静态 defaultValue(in:) 方法,该方法接受 ViewDimensions 对象并返回一个 CGFloat,指定“如果视图没有 alignmentGuide() 修饰符,该视图应该如何对齐“,将获得视图的现有 ViewDimensions 对象,因此可以选择其中一个作为默认值,也可以使用硬编码值。
  • 具体实现如下所示:
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() 提供闭包,该闭包可以根据需要定位视图。
  • 例如,可以将 CSDN 代码更新为 use.midAccountAndName,然后告诉帐户和名称使用其中心位置作为指南,明确地说,这意味着“对齐这两个视图,使它们的中心都位于 .midAccountAndName 指南上”:
struct ContentView: View 
    
    var body: some View 
        HStack(alignment: .midAccountAndName) 
            VStack 
                Text("@CSDN")
                    .alignmentGuide(.midAccountAndName)  d in d[VerticalAlignment.center] 
                Image("forever_wj")
                    .resizable()
                    .frame(width: 60, height: 60)
            

            VStack 
                Text("CSDN ID:")
                Text("Forever_wj")
                    .alignmentGuide(.midAccountAndName)  d in d[VerticalAlignment.center] 
                    .font(.title)
            
        
    

  • 那么效果就变成如下这样:

  • 这将确保它们是垂直对齐的,不管前面或后面是什么,只要有了这个示例,那么在前后添加更多的文本视图,SwiftUI 将重新定位所有内容,以确保对齐的两个视图保持不变。

以上是关于Swift之深入解析SwiftUI布局如何自定义AlignmentGuides的主要内容,如果未能解决你的问题,请参考以下文章

Swift之深入解析如何自定义操作符

Swift之深入解析如何结合Core Data和SwiftUI

Swift之深入解析SwiftUI属性包装器如何处理结构体

Swift之深入解析如何将代码添加为自定义LLDB命令

Swift之深入解析如何使用Swift UI实现3D Scroll效果

SwiftUI之深入解析如何使用组合矩形GeometryReader创建条形(柱状)图