6

I can't figure out how to align the content of this view:

I tried many different approaches:

  • Fixed sized vstack
  • setting max and min width
  • setting the size of the images, etc.

Nothing seems to work :(

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()
            }
    }
}

It's quite annoying that the Human Interface Guidelines recommend creating welcome screens such as this and they don't provide a simple to do it.

enter image description here

1
  • 3
    Look at the third row... the text isn't aligned. Commented Oct 14, 2019 at 12:43

2 Answers 2

6

Just to get a little deeper on this issue (please, consider that the @Mycroft's answer is correct): In order to get the UI shown in the question the Spacer is necessary, it's not optional. I created a minimum viable example to show exactly what would happen without the Spacer view:

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 ")
                }
            }
        }
    }
}

The result is:

enter image description here

As you can see the result is completely misaligned. So, you must add the Spacer view in order to get the alignment you want.

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

In the layout above you have "two columns", the left one with the images and the right one with the texts. If you don't specify any size, the layout system will position the images and then it will give the remaining space to the texts. But there's another option if you need to specify specific sizes: if you need the image left column to be, for example, half of the screen you can use 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

Sign up to request clarification or add additional context in comments.

Comments

5

Adding a spacer seems to do the trick :

            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()

4 Comments

If you zoom in, you'll see there's also a 1-pixel misalignment between the top two HStacks. The fact that they are roughly the same is because both first sentences happen to be long and have the same length (minus that pixel). So, did you add this Spacer() in all three HStacks and did you try alignment with different texts?
I added a spacer on all three and everything aligned.
There is a new problem now... For some reasons the last sub headline is truncated...
I also had to add .fixedSize(horizontal: false, vertical: true) to the second Text subheadline to fix the truncation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.