SwiftUI:将布局相对于中心视图进行排列

3
假设我建立了这样一个视图:
struct MyView: View {
   @State private var a: String
   @State private var b: String
   @State private var c: String

   var body: some View {
      VStack {
        HStack {
          Text(a)

          // this is the central view
          Text(b).font(.headline)
        }

        Text(c)
      }
   }
}

我希望中心文本视图(显示标签的那个)成为布局的锚点。也就是说,无论其他文本值如何更改,我希望中心文本始终保持在MyView 的正中心(文本元素的中心和MyView 的中心应该相同),其他文本元素应该围绕中心元素布局。
我该如何实现这一点?我尝试查看对齐指南,但似乎无法正确理解如何使用它们。
1个回答

3

花费一些时间详细学习对齐方式后,我成功地想出了一个解决方案,只使用堆栈和自定义对齐方式,最小化对齐指南并且不需要保存任何中间状态。它是纯声明式的,所以我认为这就是SwiftUI设计人员所期望的方式。我仍然认为可能有更好的设计,但是我们可以使用它。

struct ContentView: View {
    @State var a: String = "AAAAA"
    @State var b: String = "BBBB"
    @State var c: String = "CCCCCC"

    var body: some View {
         VStack {
            ZStack(alignment: .mid) {
                // create vertical and horizontal 
                // space to align to
                HStack { Spacer() }
                VStack { Spacer() }

                VStack(alignment: .midX) {
                    Text(self.a)

                    HStack(alignment: .center) {
                        Text(self.c)


                        Text(self.b)
                            .font(.title)
                            .border(Color.blue)
                            .alignmentGuide(.midX) { d in
                                (d[.leading] + d[.trailing])/2
                            }
                            .alignmentGuide(.midY) { d in
                                (d[.top] + d[.bottom])/2
                            }
                    }
                }
            }
            .layoutPriority(1.0)
            .overlay(CrossHair().stroke(Color.pink, lineWidth: 2))

            TextField("", text: self.$b).textFieldStyle(RoundedBorderTextFieldStyle())
        }
    }
}

fileprivate extension HorizontalAlignment {
    enum MidX : AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            return (d[.leading] + d[.trailing])/2
        }
    }

    static let midX = HorizontalAlignment(MidX.self)
}

fileprivate extension VerticalAlignment {
    enum MidY : AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            return (d[.top] + d[.bottom])/2
        }
    }

    static let midY = VerticalAlignment(MidY.self)
}

fileprivate extension Alignment {
    static let mid = Alignment(horizontal: .midX, vertical: .midY)

@kontiki 感谢您的深入评论和建议。我认为我通过消除hs状态成功改进了您的解决方案,但绝大部分功劳肯定归于您 :) - MrMobster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接