SwiftUI:将视图与 VStack 中另一个视图的前缘和后缘对齐
Posted
技术标签:
【中文标题】SwiftUI:将视图与 VStack 中另一个视图的前缘和后缘对齐【英文标题】:SwiftUI: Aligning views to the leading & trailing edges of another view in a VStack 【发布时间】:2019-12-27 07:30:18 【问题描述】:如何在 SwiftUI VStack
中将内容与另一个视图的前缘和后缘对齐?
我目前有以下 SwiftUI 代码:
struct MyBlock: View
var body: some View
Rectangle().foregroundColor(.gray).frame(width: 80, height: 80)
struct MyGridView: View
var body: some View
HStack(spacing: 16)
MyBlock()
MyBlock()
MyBlock()
struct PinPad: View
var body: some View
VStack
MyGridView()
HStack
Button(action: , label: Text("Left Align") )
Spacer()
Button(action: , label: Text("Right Align") )
结果呈现如下:
但我真正想要的是"Left Align"
Button
与MyGridView
的左/前缘对齐,"Right Align"
Button
与MyGridView
的右/后缘对齐.
例如,像这样:
我显然在这里遗漏了一些非常基本的东西,因为在 UIKit 中使用自动布局是微不足道的。
【问题讨论】:
【参考方案1】:解决布局问题需要做的第一件事是在视图上添加边框。这将使您看到视图的真实(和不可见)界限。问题会更清楚:
在您的情况下,可以通过将其全部包装在 HStack 中并添加一些垫片来轻松修复:
struct PinPad: View
var body: some View
HStack
Spacer()
VStack
MyGridView().border(Color.blue, width: 3)
HStack
Button(action: , label: Text("Left Align") ).border(Color.red, width: 3)
Spacer()
Button(action: , label: Text("Right Align") ).border(Color.red, width: 3)
.border(Color.green, width: 3)
Spacer()
【讨论】:
这当然有效。除非有人能想出一个更优雅的解决方案,否则我现在就试一试。【参考方案2】:GeometryReader
是一个视图,可让您访问父母的大小和位置
定义了一个名为 GeometryGetter 的视图,
struct GeometryGetter: View
@Binding var rect: CGRect
var body: some View
return GeometryReader geometry in
self.makeView(geometry: geometry)
func makeView(geometry: GeometryProxy) -> some View
DispatchQueue.main.async
self.rect = geometry.frame(in: .global)
return Rectangle().fill(Color.clear)
然后将代码更改如下,
struct PinPad: View
@State private var rect: CGRect = CGRect()
var body: some View
HStack
VStack
MyGridView().background(GeometryGetter(rect: $rect))
HStack
Button(action: , label: Text("Left Align") )
Spacer()
Button(action: , label: Text("Right Align") )
.frame(width: rect.width)
【讨论】:
【参考方案3】:您可以在 VStack 之后添加 .fixedSize()。
【讨论】:
【参考方案4】:将.fixedSize()
添加到您的 VStack 可以解决问题。
struct PinPad: View
var body: some View
VStack
MyGridView()
HStack
Button(action: , label: Text("Left Align") )
Spacer()
Button(action: , label: Text("Right Align") )
.fixedSize()
简要说明:
关于自动布局的基本内容,在 swiftui 中取决于框架 我们使用的不同堆栈堆栈。在这个查询中,第一个 VStack 是 父视图,它围绕它的 childView 作为它的框架 它是明确提供的。但是,由于按钮的 HStack 没有提供任何明确的宽度,但由于
Spacer()
; (这明确地使按钮拖动到它们的边缘),HStack 的 框架具有可用屏幕大小的宽度,这使得父级 VStack 视图也随之放大。因此,我们需要 还要注意子视图框架以及父视图 查看。额外信息:- 将
alignment:
添加到堆栈本身只会对齐该视图中的内容,而添加.frame(alignment:)
修饰符将对齐视图本身。
【讨论】:
以上是关于SwiftUI:将视图与 VStack 中另一个视图的前缘和后缘对齐的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI VStack 和 List 中其他视图压缩的视图