正确对齐 VStack 和 HStack

6
我不知道如何对齐此视图的内容:
我尝试了许多不同的方法:
  • 固定大小的vstack
  • 设置最大和最小宽度
  • 设置图像的大小等等。
似乎什么都不起作用 :(
import SwiftUI

struct Welcome: View {
    var body: some View {
        VStack {
            Text("Welcome to XXX")
                .font(.title).bold()

            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                    .imageScale(.large)
                    .padding()
                VStack(alignment: .leading) {
                    Text("Lorem ipsum dolor")
                        .font(.headline)
                    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore")
                        .font(.subheadline)
                        .foregroundColor(Color(.lightText))
                }
            }.padding()

            HStack {
                Image(systemName: "command")
                    .foregroundColor(Color(.systemOrange))
                    .imageScale(.large)
                    .padding()
                VStack(alignment: .leading) {
                    Text("Lorem ipsum dolor")
                        .font(.headline)
                    Text("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.")
                        .font(.subheadline)
                        .foregroundColor(Color(.lightText))
                }
            }.padding()

            HStack {
                Image(systemName: "cube")
                    .foregroundColor(Color(.systemOrange))
                    .imageScale(.large)
                    .padding()
                VStack(alignment: .leading) {
                    Text("At vero eos et accusamus")
                        .font(.headline)
                    Text("At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque ")
                        .font(.subheadline)
                        .foregroundColor(Color(.lightText))
                }
            }.padding()
                Button(action: {
                    print("skip")
                }) {
                    HStack {
                        Spacer()
                        Text("Skip")
                            .font(.subheadline)
                        Spacer()
                    }
                    .foregroundColor(Color(.systemOrange))
                }.padding(.top, 60)

                Button(action: {
                    print("continue")
                }) {
                    HStack {
                        Spacer()
                        Text("Sign In")
                            .font(.subheadline)
                        Spacer()
                    }
                    .padding(12)
                    .foregroundColor(Color(.label))
                    .background(Color(.systemOrange))
                    .cornerRadius(12)
                }.padding()
            }
    }
}


很烦人的是,人机界面指南建议创建欢迎屏幕等内容,但它们没有提供简单的方法来实现。

enter image description here


3
看第三排...文本没有对齐。 - Mycroft Canner
2个回答

6

为了更深入地了解这个问题(请注意,@Mycroft的回答是正确的),需要使用Spacer才能显示出问题中的UI,它不是可选的。我创建了一个最小化的示例,以便准确展示没有Spacer视图会发生什么:

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("Sed ut perspiciatis unde omnis iste natus")
                }
            }
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.")
                }
            }
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("At vero eos ")
                }
            }
        }
    }
}

结果是:

enter image description here

正如您所看到的,结果完全不对齐。因此,您必须添加Spacer视图以获得所需的对齐方式。
struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("Sed ut perspiciatis unde omnis iste natus")
                }
                Spacer()
            }
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.")
                }
                Spacer()
            }
            HStack {
                Image(systemName: "magnifyingglass")
                    .foregroundColor(Color(.systemOrange))
                VStack(alignment: .leading) {
                    Text("At vero eos ")
                }
                Spacer()
            }
        }
    }
}

enter image description here

在上面的布局中,您有“两列”,左侧是图像,右侧是文本。如果您没有指定任何大小,布局系统将定位图像,然后将剩余空间给予文本。但是,如果您需要指定特定的大小,则还有另一种选项:如果您需要图像左列例如为屏幕的一半,您可以使用GeometryReader
struct ContentView: View {
    var body: some View {
        GeometryReader { g in
            VStack {
                HStack {
                    HStack {
                        Spacer()
                        Image(systemName: "magnifyingglass")
                            .foregroundColor(Color(.systemOrange))
                    }
                    .frame(width: g.size.width/2.0)

                    VStack(alignment: .leading) {
                        Text("Sed ut perspiciatis unde omnis iste natus")
                    }
                    Spacer()
                }
                HStack {
                    HStack {
                        Spacer()
                        Image(systemName: "magnifyingglass")
                            .foregroundColor(Color(.systemOrange))
                    }
                    .frame(width: g.size.width/2.0)

                    VStack(alignment: .leading) {
                        Text("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Sed ut ")
                    }
                    Spacer()
                }
                HStack {
                    HStack {
                        Spacer()
                        Image(systemName: "magnifyingglass")
                            .foregroundColor(Color(.systemOrange))
                    }
                    .frame(width: g.size.width/2.0)
                    VStack(alignment: .leading) {
                        Text("At vero eos ")
                    }
                    Spacer()
                }
            }
        }
    }
}

enter image description here


5

添加一个间隔似乎就能实现效果:

            HStack {
                Image(systemName: "cube")
                    .foregroundColor(Color(.systemOrange))
                    .imageScale(.large)
                    .padding()
                VStack(alignment: .leading) {
                    Text("At vero eos et accusamus")
                        .font(.headline)
                    Text("At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque ")
                        .font(.subheadline)
                        .foregroundColor(Color(.lightText))
                }
                Spacer()
            }.padding()

如果你放大看,你会发现两个HStack的顶部之间也存在着一个1像素的错位。它们大致相同的原因是因为两个句子恰好都很长且长度相同(除了那个像素)。所以,你是在所有三个HStack中添加了这个Spacer(),并尝试使用不同的文本对齐吗? - meaning-matters
我在所有三个上添加了一个间隔,一切对齐了。 - Mycroft Canner
现在有一个新问题...由于某些原因,最后一个子标题被截断了... - Mycroft Canner
我还需要在第二个文本子标题中添加.fixedSize(horizontal: false, vertical: true)来修复截断问题。 - Mycroft Canner

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