SwiftUI VStack对齐到右侧单元素

13

我刚接触SwiftUI,这次我想将单独的元素(一张图片)向右对齐,然后将其余内容居中对齐。

就像在HStack上使用Spacer()时发生的情况,但是对于另一侧。

我阅读了关于.alignmentGuide的文章,有点困惑,但我尝试这样使用:

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Text("Hello!").alignmentGuide(.trailing) {
                    v in v[HorizontalAlignment.trailing]
                }
            }
            Text("Hello, World!")
            Spacer()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

但这并没有任何改变,两个 Text 都居中对齐。

我尝试将 .alignmentGuide 代码移动到与 HStack} 后面,结果相同。

我想要实现的是,在使用故事板之前,我会使用一些约束条件来完成这个任务,例如将右侧约束条件设置为 8 或其他数值,但是当涉及到 SwiftUI 时,我有点困惑。

enter image description here

2个回答

22

这是其中一种方法:

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Text("Hello!")
                    .padding(.trailing, 8)
            }
            Text("Hello, World!")
            Spacer()
        }
    }
}

使用带有 Spacer()HStackText("Hello!") 推到右边。添加 .padding(.trailing, 8) 使其保持在右边缘偏移 8 点。


4
这真的是推荐的实现方式吗?对于像 align-self: flex-end 这样基本的属性来说,听起来有点啰嗦。 - Jonas Sourlier
你说得对,我不认为这是推荐的做法。请查看我的回答以获得更多解释。 - Rémi B.

11

回答@cheesus的问题,我会说@vacawama的回答不是推荐的做法。

这是我会怎么做

VStack {
  Text("Hello!")
    .frame(maxWidth: .infinity, alignment: .trailing)
    .padding(.trailing, 8)
  Text("Hello, World!")
}
.frame(maxHeight: .infinity, alignment: .top)

再详细解释一下

使用 (H|V)StackSpacer 的主要问题是你会在你的内容和 Spacer 之间得到固定的间距,而在某些情况下这可能会引起问题。

一个例子

  • Consider we want a HStack, some spacing between elements and the last text aligned to the left:

    HStack(spacing: 25) {
      Color.red
        .frame(width: 50, height: 20)
      Color.green
        .frame(width: 50, height: 20)
      Text("The text")
        .background(Color.blue)
      Spacer()
    }
    .frame(width: 250)
    .border(Color.yellow)
    .padding(8)
    

    It gives: Example 1

  • If the text becomes longer, you see the HStack spacing between the spacer:

    - Text("The text")
    + Text("Some long text")
    

    Example 2

  • Now I just replaced the Spacer with a Color so you can see it in action:

    - Text("Some long text")
    -   .background(Color.blue)
    - Spacer()
    + Text("Some long text")
    +   .background(Color.blue)
    +   .layoutPriority(1)
    + Color.indigo
    +   .frame(height: 20)
    +   .frame(maxWidth: .infinity)
    

    Example 3

  • This is fixed if you use .frame(alignment:):

    HStack(spacing: 25) {
      Color.red
        .frame(width: 50, height: 20)
      Color.green
        .frame(width: 50, height: 20)
      Text("Some long text")
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color.blue)
    }
    .frame(width: 250)
    .border(Color.yellow)
    .padding(8)
    

    Example 4


1
这个答案似乎比被接受的答案更好。 - eharo2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接