SwiftUI在ZStack中未居中

SwiftUI在ZStack中未居中,swiftui,Swiftui,我试图组合一个视图,该视图由顶部标题视图、底部内容视图和位于顶部的视图组成,该视图位于分割两个视图的线的中心。我发现我需要一个ZStack中的对齐指南来定位中间视图,但是我在将较低内容视图中的项目居中而没有间隙时遇到了问题 此代码: extension VerticalAlignment { struct ButtonMid: AlignmentID { static func defaultValue(in context: ViewDimensions) ->

我试图组合一个视图,该视图由顶部标题视图、底部内容视图和位于顶部的视图组成,该视图位于分割两个视图的线的中心。我发现我需要一个ZStack中的对齐指南来定位中间视图,但是我在将较低内容视图中的项目居中而没有间隙时遇到了问题

此代码:

extension VerticalAlignment {
    struct ButtonMid: AlignmentID {
        static func defaultValue(in context: ViewDimensions) -> CGFloat {
            return context[.bottom]
        }
    }
    static let buttonMid = VerticalAlignment(ButtonMid.self)
}

struct ContentView: View {
    var body: some View {
        VStack {
            ZStack(alignment: Alignment(horizontal: .center, vertical: .buttonMid)) {
                HeaderView()
                    .frame(maxWidth: .infinity, minHeight: 200, idealHeight: 200, maxHeight: 200, alignment: .topLeading)
                
//                BodyView()
//                    .alignmentGuide(.buttonMid, computeValue: { dimension in
//                        return dimension[VerticalAlignment.top]
//                    })
                
                Color.red
                    .frame(width: 380, height: 50, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    .alignmentGuide(.buttonMid, computeValue: { dimension in
                        return dimension[VerticalAlignment.center]
                    })
            }
            
            BodyView()
        }
        .edgesIgnoringSafeArea(.top)
    }
}

struct HeaderView: View {
    var body: some View {
        Color.green
    }
}

struct BodyView: View {
    var body: some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
                BodyContent()
                Spacer()
            }
            Spacer()
        }
        .background(Color.blue)
    }
}

struct BodyContent: View {
    var body: some View {
        VStack {
            Text("Line 1")
            Text("Line 2")
            Text("Line 3")
        }
    }
}
给你这个:

它以我想要的方式将较低的内容居中,但在上下视图之间留有间隙。如果我在ZStack中取消对BodyView代码的注释,并在VStack中对其进行注释,如下所示:

struct ContentView: View {
    var body: some View {
        VStack {
            ZStack(alignment: Alignment(horizontal: .center, vertical: .buttonMid)) {
                HeaderView()
                    .frame(maxWidth: .infinity, minHeight: 200, idealHeight: 200, maxHeight: 200, alignment: .topLeading)
                
                BodyView()
                    .alignmentGuide(.buttonMid, computeValue: { dimension in
                        return dimension[VerticalAlignment.top]
                    })
                
                Color.red
                    .frame(width: 380, height: 50, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    .alignmentGuide(.buttonMid, computeValue: { dimension in
                        return dimension[VerticalAlignment.center]
                    })
            }
            
//            BodyView()
        }
        .edgesIgnoringSafeArea(.top)
    }
}
给你:


这使得内容没有中心。我怎样才能使它居中?我试着把它放在GeometryReader中,得到了相同的结果。

您不需要自定义
垂直对齐。相反,您可以将中间视图作为覆盖,并将其与底部视图的上边框对齐:

struct ContentView: View {
    var body: some View {
        VStack(spacing: 0) {
            HeaderView()
                .frame(height: 200)
            BodyView()
                .overlay(
                    Color.red
                        .frame(width: 380, height: 50)
                        .alignmentGuide(.top) { $0[VerticalAlignment.center] },
                    alignment: .top
                )
        }
        .edgesIgnoringSafeArea(.top)
    }
}
除了需要在VStack上使用“间距:0”外,它还非常有效。谢谢