layout - SwiftUI:相对于中央 View 进行布局

标签 layout swiftui

假设我构建了一个这样的 View :

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)
      }
   }
}

我希望中央 TextView (显示 b 的 View )成为布局的 anchor 。也就是说,无论其他文本值如何变化,我都希望中心文本始终位于 MyView 的中心(文本元素的中心和 MyView 应保持相同),其他文本元素应围绕中心元素布置。

我该如何实现?我试图查看对齐指南,但我似乎不明白如何正确使用它们。

最佳答案

在花了一些时间详细了解对齐的工作原理后,我设法找到了一个仅使用堆栈和自定义对齐的解决方案,其中包含最少的对齐指南,并且无需保存任何中间状态。它纯粹是声明性的,所以我想这就是 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)

关于layout - SwiftUI:相对于中央 View 进行布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57704623/

相关文章:

android - 在 android 的 Gallery 中添加 Relativelayout 或 listview?

Java GUI 布局建议

c++ - MSVC 对象布局怪癖

silverlight - 如何在 SL 中使用可移动引线实现语音气泡自定义边框

java - Android - 如何根据屏幕尺寸和按钮动态地以编程方式添加按钮?

ios - SwiftUI:警报自动关闭(当它不应该时!)

ios - View 以 super View 为中心,在 SwiftUI 中 View 位于其顶部

ios - 是否可以在 SwiftUI 中将 "Presentation Hosting Controller"背景颜色设置为透明而不是白色?

swiftui - 如何使一个 View 中的两个列表在 SwiftUI 中作为一页滚动?

swiftui - 如何在 SwiftUI 中打印()到 Xcode 控制台?