Eva*_*van 3 centering swift swiftui vstack hstack
如果水平堆栈中有 3 个项目,我想我可以这样做:
HStack{
Text("test")
Spacer()
item2()
Spacer()
Text("test")
}
Run Code Online (Sandbox Code Playgroud)
将 item2() 置于两个文本视图之间的中心。然而,这样做的问题是 item2() 不一定总是居中,因为,可以说 Text("test") 更改为 Text("a") 或其他内容。这会导致问题,并且第二个项目并不总是位于屏幕中央。
我怎样才能使 item2() 始终居中?
谢谢
我建议以下起点(最简单的情况......请阅读下面的原因)

正如所见,它确实提供了居中的无框架移位和正确对齐的侧面元素,但是......有一个缺点-只有事先知道这三个文本元素在用户中永远不应该重叠,它才会在这种最简单的变体中工作运行。如果是这样的话(确实有这样的情况),那么这种方法就可以了。但是,如果左/右文本可能在运行时增长,则需要更多的计算来根据.frame(maxWidth:)居中元素的宽度来限制它们的宽度......该变体更复杂,但它是可行的。
var body: some View {
ZStack {
HStack {
Text("Longer side")
Spacer()
Text("One")
}
item2()
}
}
private func item2() -> some View {
Text("CENTER")
.background(Color.yellow)
.border(Color.red)
}
Run Code Online (Sandbox Code Playgroud)
更新:这是限制一侧不重叠居中的可能方法(包含异步更新,因此应在实时预览或模拟器中进行测试)
所以...如果左侧文本是动态的并且需要剪切尾随符号,那么它可能会这样...

并且它会自动适应设备方向的变化

struct TestHorizontalPinCenter: View {
@State var centerFrame: CGRect = .zero
private let kSpacing: CGFloat = 4.0
var body: some View {
ZStack {
HStack {
Text("Longer side very long text to fit")
.lineLimit(1)
.frame(maxWidth: (centerFrame == .zero ? .infinity : centerFrame.minX - kSpacing), alignment: .leading)
Spacer()
Text("One")
}
item2()
.background(rectReader($centerFrame))
}
}
private func item2() -> some View {
Text("CENTER")
.background(Color.yellow)
.border(Color.red)
}
func rectReader(_ binding: Binding<CGRect>) -> some View {
return GeometryReader { (geometry) -> AnyView in
let rect = geometry.frame(in: .global)
DispatchQueue.main.async {
binding.wrappedValue = rect
}
return AnyView(Rectangle().fill(Color.clear))
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要包裹左侧,则.lineLimit(nil)需要额外的布局,以及解决方案的增长,但想法是相同的。希望这对某人有帮助。
| 归档时间: |
|
| 查看次数: |
2538 次 |
| 最近记录: |