Skip to main content

VStack

Definition

VStack is a SwiftUI container view that arranges its child views in a vertical line from top to bottom. It's one of the fundamental building blocks for creating user interfaces in SwiftUI.

Basic Syntax

VStack {
Text("First")
Text("Second")
Text("Third")
}

VStack with Spacing

// Default spacing
VStack {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}

// Custom spacing
VStack(spacing: 20) {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}

// No spacing
VStack(spacing: 0) {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}

VStack with Alignment

// Leading alignment
VStack(alignment: .leading) {
Text("Short")
Text("Medium Text")
Text("Very Long Text Here")
}

// Center alignment (default)
VStack(alignment: .center) {
Text("Short")
Text("Medium Text")
Text("Very Long Text Here")
}

// Trailing alignment
VStack(alignment: .trailing) {
Text("Short")
Text("Medium Text")
Text("Very Long Text Here")
}

Combining Spacing and Alignment

VStack(alignment: .leading, spacing: 15) {
Text("Title")
.font(.headline)
Text("Subtitle")
.font(.subheadline)
Text("This is the main content area with more text")
.font(.body)
}

Nested VStacks

VStack(spacing: 20) {
VStack(alignment: .leading) {
Text("Section 1")
.font(.title)
Text("Content for section 1")
}

VStack(alignment: .leading) {
Text("Section 2")
.font(.title)
Text("Content for section 2")
}
}

VStack with Different View Types

VStack(spacing: 15) {
Text("Welcome")
.font(.largeTitle)

Image(systemName: "star.fill")
.foregroundColor(.yellow)
.font(.system(size: 50))

Button("Tap Me") {
print("Button tapped")
}
.buttonStyle(.borderedProminent)

TextField("Enter text", text: $inputText)
.textFieldStyle(.roundedBorder)
.padding(.horizontal)
}

VStack with ForEach

VStack(spacing: 10) {
ForEach(0..<5) { index in
Text("Row \(index)")
.padding()
.frame(maxWidth: .infinity)
.background(Color.blue.opacity(0.3))
.cornerRadius(8)
}
}

VStack with Conditional Content

VStack(spacing: 15) {
Text("User Profile")
.font(.title)

if isLoggedIn {
Text("Welcome back, \(username)!")
Button("Logout") {
// Logout action
}
} else {
Text("Please log in")
Button("Login") {
// Login action
}
}
}

VStack with Spacer

// Push content to top
VStack {
Text("Top Content")
Spacer()
}

// Push content to bottom
VStack {
Spacer()
Text("Bottom Content")
}

// Center content
VStack {
Spacer()
Text("Centered Content")
Spacer()
}

// Distribute content
VStack {
Text("Top")
Spacer()
Text("Middle")
Spacer()
Text("Bottom")
}

VStack with Divider

VStack(spacing: 0) {
Text("Section 1")
.padding()

Divider()

Text("Section 2")
.padding()

Divider()

Text("Section 3")
.padding()
}

Styled VStack Examples

// Card style
VStack(alignment: .leading, spacing: 10) {
Text("Card Title")
.font(.headline)
Text("Card description text goes here")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)

// Form-like layout
VStack(alignment: .leading, spacing: 20) {
VStack(alignment: .leading, spacing: 5) {
Text("Email")
.font(.caption)
.foregroundColor(.secondary)
TextField("Enter email", text: $email)
.textFieldStyle(.roundedBorder)
}

VStack(alignment: .leading, spacing: 5) {
Text("Password")
.font(.caption)
.foregroundColor(.secondary)
SecureField("Enter password", text: $password)
.textFieldStyle(.roundedBorder)
}

Button("Sign In") {
// Sign in action
}
.frame(maxWidth: .infinity)
.buttonStyle(.borderedProminent)
}
.padding()

VStack with ScrollView

ScrollView {
VStack(spacing: 20) {
ForEach(0..<20) { index in
Text("Item \(index)")
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
}
}
.padding()
}

VStack vs LazyVStack

// Regular VStack - loads all views immediately
VStack {
ForEach(0..<100) { index in
Text("Item \(index)")
}
}

// LazyVStack - loads views on demand (better performance)
ScrollView {
LazyVStack {
ForEach(0..<100) { index in
Text("Item \(index)")
}
}
}

Common Patterns

Profile Header

VStack(spacing: 15) {
Image(systemName: "person.circle.fill")
.resizable()
.frame(width: 100, height: 100)
.foregroundColor(.blue)

Text("John Doe")
.font(.title)
.bold()

Text("iOS Developer")
.font(.subheadline)
.foregroundColor(.secondary)

HStack(spacing: 20) {
VStack {
Text("1.2K")
.font(.headline)
Text("Followers")
.font(.caption)
}

VStack {
Text("342")
.font(.headline)
Text("Following")
.font(.caption)
}
}
}
.padding()

List Item

VStack(alignment: .leading, spacing: 5) {
Text("Item Title")
.font(.headline)
Text("Subtitle or description")
.font(.subheadline)
.foregroundColor(.secondary)
Text("Additional info")
.font(.caption)
.foregroundColor(.gray)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.gray.opacity(0.1))
.cornerRadius(8)

Status Message

VStack(spacing: 10) {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 60))
.foregroundColor(.green)

Text("Success!")
.font(.title)
.bold()

Text("Your action was completed successfully")
.multilineTextAlignment(.center)
.foregroundColor(.secondary)
}
.padding()

Performance Considerations

// For long lists, use LazyVStack
ScrollView {
LazyVStack(spacing: 10) {
ForEach(items) { item in
ItemView(item: item)
}
}
}

// For small, fixed number of items, regular VStack is fine
VStack(spacing: 10) {
HeaderView()
ContentView()
FooterView()
}

Best Practices

  1. Use appropriate spacing: Choose spacing that creates visual hierarchy
  2. Consider alignment: Use leading/trailing alignment for text-heavy content
  3. Use LazyVStack for long lists: Better performance with many items
  4. Combine with Spacer: Control vertical distribution of content
  5. Nest sparingly: Too many nested stacks can impact performance
  6. Use ForEach for dynamic content: Makes code cleaner and more maintainable
  7. Consider ScrollView: Add when content might exceed screen height

Common Use Cases

  • Form layouts: Stacking input fields vertically
  • Profile screens: User info, stats, and actions
  • Settings screens: Groups of related options
  • Card layouts: Vertical content in cards
  • List items: Custom row layouts
  • Navigation flows: Step-by-step content
  • Status screens: Success/error messages with icons
  • HStack: Horizontal arrangement of views
  • ZStack: Overlapping views
  • LazyVStack: Lazy-loading vertical stack for better performance
  • List: Native list view with built-in features
  • ScrollView: Makes content scrollable