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
- Use appropriate spacing: Choose spacing that creates visual hierarchy
- Consider alignment: Use leading/trailing alignment for text-heavy content
- Use LazyVStack for long lists: Better performance with many items
- Combine with Spacer: Control vertical distribution of content
- Nest sparingly: Too many nested stacks can impact performance
- Use ForEach for dynamic content: Makes code cleaner and more maintainable
- 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
Related Views
- 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