假设有以下 HStack:
HStack{
Text("View1")
Text("Centre")
Text("View2")
Text("View3")
}
如何强制“中心”视图在中心位置?
这里是可能的简单方法。已在Xcode 11.4 / iOS 13.4下测试通过
struct DemoHStackOneInCenter: View {
var body: some View {
HStack{
Spacer().overlay(Text("View1"))
Text("Centre")
Spacer().overlay(
HStack {
Text("View2")
Text("View3")
}
)
}
}
}
该解决方案增加了对左/右侧视图的对齐方式,详见相对于另一个居中视图定位视图
的回答。这个答案需要几个步骤:
对于必须填充VStack的视图,我使用了Geometry Reader。这会自动扩展以占据父视图的大小,而不会影响布局。
import SwiftUI
//Custom Alignment Guide
extension HorizontalAlignment {
enum SubCenter: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
d[HorizontalAlignment.center]
}
}
static let subCentre = HorizontalAlignment(SubCenter.self)
}
struct CentreSubviewOfHStack: View {
var body: some View {
//VStack Alignment set to the custom alignment
VStack(alignment: .subCentre) {
HStack{
Text("View1")
//Centre view aligned
Text("Centre")
.alignmentGuide(.subCentre) { d in d.width/2 }
Text("View2")
Text("View3")
}
//Geometry reader automatically fills the parent
//this is aligned with the custom guide
GeometryReader { geometry in
EmptyView()
}
.alignmentGuide(.subCentre) { d in d.width/2 }
}
}
}
struct CentreSubviewOfHStack_Previews: PreviewProvider {
static var previews: some View {
CentreSubviewOfHStack()
.previewLayout(CGSize.init(x: 250, y: 100))
}
}
注意:本回答假设您可以设置包含 VStack 的固定高度和宽度。这将防止 GeometryReader 过度“推出”。
在另一种情况下,我用一个矩形替换了 GeometryReader:
//rectangle fills the width, then provides a centre for things to align to
Rectangle()
.frame(height:0)
.frame(idealWidth:.infinity)
.alignmentGuide(.colonCentre) { d in d.width/2 }
HStack {
// Fills the left side
VStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 120, height: 200)
}.frame(maxWidth: .infinity)
// Centered
Rectangle()
.foregroundColor(Color.red)
.frame(width: 50, height: 150)
// Fills the right side
VStack {
HStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 25, height: 100)
Rectangle()
.foregroundColor(Color.red)
.frame(width: 25, height: 100)
}
}.frame(maxWidth: .infinity)
}.border(Color.green, width: 3)
HStack
在可用空间的整个宽度上展开,并将其中心元素固定在中心位置。HStack(spacing: .zero) {
Spacer()
.overlay {
HStack(spacing: .zero) {
Text("View 1")
Spacer()
}
}
Text("Centre")
Spacer()
.overlay {
HStack(spacing: .zero) {
Spacer()
Text("View 2")
}
}
}