如果我在水平堆栈中有3个项目,我想我可以做这样的事情:
HStack{
Text("test")
Spacer()
item2()
Spacer()
Text("test")
}
将item2()置于两个Text视图之间的中心位置。但是,这样做的问题是item2()不一定总是居中,因为可以说Text(“ test”)更改为Text(“ a”)或其他内容。这会导致问题,并且第二个项目并不总是在屏幕上居中。
如何使item2()始终居中?
谢谢
答案 0 :(得分:1)
我将提出以下起点(最简单的情况...请在下面阅读原因)
如所见,它确实提供了带有正确对齐的侧边元素的居中偏移/无帧偏移,但是...存在缺点-它仅适用于最简单的变体 如果事先知道在用户运行时这三个文本元素永远不应该重叠。如果是这种情况(确实有这种情况),那么这种方法就可以了。但是,如果左/右文本可能会在运行时增长,则将需要更多计算以根据中心元素的宽度来限制.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)
}
更新:这是一种可以限制一侧不重叠居中的方法(包含异步更新,因此应在 Live Preview 或模拟器中进行测试)< / p>
所以...如果左侧文本是动态的,并且要求剪切尾随符号,那么这就是可能的方式...
它会自动适应设备方向的变化
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))
}
}
}
如果需要包装左侧,则将需要.lineLimit(nil)
和其他布局,以及解决方案的增长,但是想法是相同的。希望这对某人有帮助。
答案 1 :(得分:1)
我遇到了同样的问题,@ Asperi的解决方案也起作用了,但是如果我在列表中使用多行文本,则会遇到一些性能问题,并且会遇到一些性能问题。
以下解决方案解决了所有问题。
HStack(alignment: .center) {
Text("test")
.frame(maxWidth: .infinity)
item2()
Text("test")
.frame(maxWidth: .infinity)
}
答案 2 :(得分:0)
您可能需要添加一些自定义的Alignment组件。
extension HorizontalAlignment{
private enum MyHAlignment: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[HorizontalAlignment.center]
}
}
static let myhAlignment = HorizontalAlignment(MyHAlignment.self)
}
HStack{
Spacer()
Text("jjjjjjjjjj")
Spacer()
Image("image").alignmentGuide(.myhAlignment) { (ViewDimensions) -> CGFloat in
return ViewDimensions[HorizontalAlignment.center]
}
Spacer()
Text("test")
}.frame(alignment: Alignment(horizontal: .myhAlignment, vertical: .center))
答案 3 :(得分:0)
要使视图居中,可以使用ZStack:
ZStack {
item2()
HStack {
Text("test")
Spacer()
Text("test")
}
}