SwiftUI如何在VStack内部垂直居中放置视图

问题描述

我想在屏幕的垂直中心有一个视图,在屏幕的顶部有一个视图,在这两个视图之间垂直居中有一个视图,就像这样:

enter image description here

这花了我5分钟时间在情节提要上做,但是我似乎找不到在SwiftUI?中做这件事的方法

我已经尝试了多个zstack,vstack,多个自定义对齐方式,但这是我得到的最接近的结果:

struct SelectionView: View {
    var body: some View {
        ZStack(alignment: .myAlignment) {
            Color.green
                .edgesIgnoringSafeArea(.all)
            
            
            vstack {
                Image(systemName: "clock")
                    .resizable()
                    .foregroundColor(.white)
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 156,height: 80)
                
//                Spacer()
                
                Text("My\nmultiline label")
                    .multilineTextAlignment(.center)
                    .font(.title)
                    .foregroundColor(.white)

//                Spacer()
                
                vstack(spacing: 16) {
                    RoundedRectangle(cornerRadius: 5).fill(Color.white).frame(height: 79)
                    RoundedRectangle(cornerRadius: 5).fill(Color.white).frame(height: 79)
                }
                .alignmentGuide(VerticalAlignment.myAlignment) { dimension in
                    dimension[VerticalAlignment.center]
                }
                .layoutPriority(1)
            }
            .padding([.leading,.trailing],24)
        }
    }
    
}

struct SelectionView_Previews: PreviewProvider {
    static var previews: some View {
        LanguageSelectionView()
    }
}

// MARK

extension HorizontalAlignment {
  
    enum MyHorizontal: AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat
                 { d[HorizontalAlignment.center] }
    }

    static let myAlignment =
                 HorizontalAlignment(MyHorizontal.self)
}

extension VerticalAlignment {
    enum MyVertical: AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat
                 { d[VerticalAlignment.center] }
    }
  
    static let myAlignment = VerticalAlignment(MyVertical.self)
}

extension Alignment {
    static let myAlignment = Alignment(horizontal: .myAlignment,vertical: .myAlignment)
}

我将GeometryReader保留为最后的手段,因为对于这种看似简单的布局来说,这似乎太过严格了。

我想我正在以某种错误的方式来处理这个问题(我的头上仍然有太多UIKit /约束)。

解决方法

这是可能的解决方案。经过Xcode 12 / iOS 14的测试

demo

struct SelectionView: View {
    var body: some View {
        ZStack {
            Color.green
                .edgesIgnoringSafeArea(.all)
            
            VStack(spacing: 16) {
                Color.clear
                    .overlay(
                        VStack {
                            Image(systemName: "clock")
                                .resizable()
                                .foregroundColor(.white)
                                .aspectRatio(contentMode: .fit)
                                .frame(width: 156,height: 80)
                            Color.clear
                                .overlay(
                                    Text("My\nmultiline label")
                                        .multilineTextAlignment(.center)
                                        .font(.title)
                                        .foregroundColor(.white)
                            )
                        }
                    )
                RoundedRectangle(cornerRadius: 5).fill(Color.white).frame(height: 79)
                RoundedRectangle(cornerRadius: 5).fill(Color.white).frame(height: 79)
                Color.clear
            }
            .padding([.leading,.trailing],24)
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...