jo.*_*.On 10 vertical-alignment swiftui vstack
我希望在屏幕垂直中心有一个视图,在屏幕顶部有一个视图,在这两个视图之间垂直居中有一个视图,如下所示:
这花了我 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)
}
Run Code Online (Sandbox Code Playgroud)
我将 GeometryReader 作为最后的手段,因为对于这个看似简单的布局来说,它感觉过于严厉。
我想我正在以某种错误的方式处理这个问题(我脑子里仍然有太多的 UIKit/约束)..
这是可能的解决方案。使用 Xcode 12 / iOS 14 进行测试
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13619 次 |
| 最近记录: |