Reputation: 1997
I can't figure out how to align the content of this view:
I tried many different approaches:
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.
Upvotes: 6
Views: 4333
Reputation: 13012
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:
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()
}
}
}
}
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()
}
}
}
}
}
Upvotes: 6
Reputation: 1997
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()
Upvotes: 5