leading edge for VStack in SwiftUI - ios

I want to create a VStack of many Texts with 20 points of spacing between each Text. I want my VStack to be aligned to left side of the screen(or leading side of parent View).

Try this:
struct ContentView: View {
var body: some View {
HStack(){
//alignment options: .center , .leading , .trailing
VStack(alignment: .leading, spacing: 20){
Text("Salam")
Text("chetori")
Text("Arsalan")
Text("?")
}
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
and if you want your VStack to be on right side of your screen, put the Spacer above the VStack

VStack(alignment: .leading, spacing: 20){
ForEach(0..<20) { i in
HStack {
Text("\(i)")
.multilineTextAlignment(.leading) // needed only if your text has multiple lines
Spacer()
}
}
}.padding()
And the result:

Related

How to align text to the top of screen?

I'm looking how to align text to the top of screen, do you know how to?
import SwiftUI
struct RegisterSignInScreen: View {
var body: some View {
VStack {
Text("Welcome Back!")
.font(.title)
.fontWeight(.bold)
.multilineTextAlignment(.center)
.padding(.bottom, 5.0)
Text("Please sign in to your account")
.font(.subheadline)
.fontWeight(.bold)
.foregroundColor(Color.gray)
.multilineTextAlignment(.center)
}
}
}
struct RegisterSignInScreen_Previews: PreviewProvider {
static var previews: some View {
RegisterSignInScreen()
}
}
image
I tried to embed my VStack in a ZStack:
ZStack(alignment: .top)
But it didn't work.
To see why this is happening you can add a background to your VStack or ZStack
ZStack {
VStack {
//Text items
}
}
.background(.red)
What you will notice (maybe unexpectedly) is that the stack is only as big as it needs to be to contain the text items.
When you add alignment to the stack it aligns the content within the stack to the specified edge of the relatively small stack. It doesn't align the stack to an edge of the screen, or change the size of the stack. What you're actually looking to do is align the stack, not it's content.
In order to align to the top of the screen you can make the stack fill the entire height of the screen. Either by adding a Spacer() at the bottom of the VStack that will fill the remaining vertical space pushing the content upwards, or by applying a frame with .infinity maxHeight: and top aligned content to the VStack.
VStack {
Text("Hello World!")
Spacer()
}
VStack {
Text("Hello World!")
}
.frame(maxHeight: .infinity, alignment: .top)
Alternatively if required for your view, you can do a similar thing with a second stack containing your text stack like so:
var body: some View {
VStack {
welcomeText
Spacer()
}
}
var welcomeText: some View {
VStack {
Text("Welcome Back!")
.font(.title)
.fontWeight(.bold)
.multilineTextAlignment(.center)
.padding(.bottom, 5.0)
Text("Please sign in to your account")
.font(.subheadline)
.fontWeight(.bold)
.foregroundColor(Color.gray)
.multilineTextAlignment(.center)
}
}
You can do this in a couple of ways, but the most obvious way is to simply add a Spacer() in the bottom of the VStack
Like so:
struct RegisterSignInScreen: View {
var body: some View {
VStack {
Text("Welcome Back!")
Text("Please sign in to your account")
Spacer() // <- HERE
}
}
}
This will push your content in the VStack to the top.
Alternatively, you can add a frame modifier and force your VStack height and add the alignment there using .frame
struct RegisterSignInScreen: View {
var body: some View {
VStack {
Text("Welcome Back!")
Text("Please sign in to your account")
}
.frame(maxHeight: .infinity, alignment: .top) // <- HERE
}
}
ZStack(alignment: .top) works, but not the same way as you think)
try to do:
ZStack(alignment: .top){
}
.background(Color.green)
and you will understand why so :)
you need to use spacer :)
VStack {
YourView()
Spacer()
}

Animate only one view inside VStack

My main view is as simple as follows:
VStack(alignment: .center, spacing: .spacing4) {
ExpandableView() // some params for title etc, not relevant
ExpandableView()
}
.padding(.horizontal, 10)
.padding(.vertical, 18)
While my ExpandableView is as follows:
public struct ExpandableView: View {
#State var showExpanded = false
public var body: some View {
VStack(alignment: .leading, spacing: .spacing2) {
HStack(spacing: .spacing2, content: {
Text("Title")
Spacer()
arrowView // The chevron image
})
.contentShape(Rectangle()) // so the complete HStack is tappable
.onTapGesture {
withAnimation(.spring()) {
showExpanded.toggle()
}
}
.animation(nil)
if showExpanded {
Text("The expanded text underneath the title goes here")
.transition(.opacity.combined(with: .flipFromTop))
}
}
}
As you can see in the image, when I expand the second view in the main VStack, the first one animates too, what am I doing wrong here?

How to align the icon in grid in SwiftUI?

So I have this code which basically shows three grid items next to each other,
import SwiftUI
struct ContentView: View {
let columns = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
Button(action: {}) {
VStack {
Image(systemName: "tray")
.font(.system(size: 40.0))
Text("Item 1")
}
}
Button(action: {}) {
VStack {
Image(systemName: "tray")
.font(.system(size: 40.0))
Text("Item 2")
}
}
Button(action: {}) {
VStack {
Image(systemName: "tray")
.font(.system(size: 40.0))
Text("Item 935835050350")
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
And it looks like this,
As you can see the text pushes icon to the top. I want text to move down and icon's position to remain constant i.e. aligned with the adjacent icons. How do I do that?
You need explicit alignment in grid items, like
struct ContentView: View {
let columns = [
GridItem(.flexible(), alignment: .top), // << this !!
GridItem(.flexible(), alignment: .top),
GridItem(.flexible(), alignment: .top)
]
...

SwiftUI. How to align root view to the left top corner?

I am learning SwiftUI. I have this code:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text("Vasia")
Text("Auuuuuuuuuuu")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
After compilation I get this:
I want these strings to be at the left top corner, not in the center. How to achieve this?
Here is possible solution:
var body: some View {
VStack(alignment: .leading) {
Text("Vasia")
Text("Auuuuuuuuuuu")
Spacer()
}.frame(maxWidth: .infinity, alignment: .leading)
}
You can use Spacer() and wrap it inside HStack and VStack like this
struct ContentView: View {
var body: some View {
HStack {
VStack(alignment: .leading, spacing: 0) {
Text("Vasia")
Text("Auuuuuuuuuuu")
Spacer()
}
Spacer()
}
}
}

Padding HStack in the top of any screen

I want to put an HStack which contains two Texts in the top of any device screen.
the problem is when I use padding that I have to decide fixed size of padding.
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
HStack(spacing: 10) {
Text("Hello world!")
Text("Hello world!")
}.padding(.top, 100)
Spacer()
}
}
}

Resources