Skip to content

How to use Spacer in SwiftUI | SwiftUI Bootcamp #12

Spacer is the flex muscle of SwiftUI layouts — it greedily consumes available space, pushing other views apart. After this lesson you'll know how to build navigation bars, pinned bottom buttons, and split layouts by placing Spacers strategically within stacks.

What You'll Learn

  • What Spacer actually is and how it expands to fill available space
  • How to use a Spacer in an HStack to push items to opposite ends (navigation bar pattern)
  • How to use a Spacer in a VStack to pin a view to the bottom of the screen

Mental Model

Think of a Spacer as a rubber band stretched between the items on either side of it. When there's extra space in the stack, the rubber band stretches to absorb it all, pushing the items on either side toward the edges. The rubber band doesn't care how much space is available — it always takes every last point.

Put one Spacer between two items in an HStack and the left item goes to the leading edge, the right item goes to the trailing edge. Put a Spacer at the end of a VStack and all the content gets pushed to the top with empty space below. Multiple Spacers split the available space evenly between them.

Detailed Explanation

Spacer is a view that has no visual representation — it's invisible. Its only behavior is to expand as much as possible along the axis of its parent stack. In a VStack, it expands vertically. In an HStack, it expands horizontally. Outside a stack it expands in both dimensions.

Spacer has a minLength parameter that sets a minimum expansion (default is the system minimum, ~8pt). If the stack doesn't have enough room to accommodate even the minimum, the spacer collapses further. You can also set Spacer(minLength: 0) to allow the spacer to fully collapse.

A common layout pattern: a navigation bar row is an HStack with a close button, a Spacer(), and a settings icon. The Spacer fills all the space between them, pushing the buttons to opposite edges regardless of screen width.

Another pattern: a screen with content at the top and a button pinned to the bottom is a VStack with the content first, a Spacer(), then the button. The spacer consumes all empty space, pushing the button to the very bottom.

The key insight is that Spacer works at the stack level — it pushes views apart within a stack. It doesn't affect views in sibling stacks or views outside its immediate container.

Code Structure

The sample is in SpacerBootcamp.swift and demonstrates both patterns: an HStack with a Spacer between two icons to create a navigation bar row, and a Spacer between the nav bar and a pinned rectangle to push it to the bottom of the screen.

Complete Code

SpacerBootcamp.swift

swift
import SwiftUI

struct SpacerBootcamp: View {
    var body: some View {
        VStack {
            HStack(spacing: 0) { // zero spacing so the spacer controls all horizontal distribution
                Image(systemName: "xmark")
                Spacer() // pushes xmark to the left and gear to the right
                Image(systemName: "gear")
            }
            .font(.title)
            //.background(Color.yellow) // uncomment to visualize the HStack's full width
            .padding(.horizontal)     // prevents icons from touching the screen edges
            //.background(Color.blue)   // uncomment to see padding's effect on the HStack background
            
            Spacer() // pushes everything above it up and the rectangle below it down
            
            Rectangle()
                .frame(height: 55) // a fixed-height bar pinned to the bottom of the screen
            
        }
        //.background(Color.yellow) // uncomment to visualize the VStack's full height
    }
}

struct SpacerBootcamp_Previews: PreviewProvider {
    static var previews: some View {
        SpacerBootcamp()
    }
}

Code Walkthrough

  1. Outer VStack — Contains the navigation bar HStack, a vertical Spacer, and the bottom Rectangle. The VStack fills the full screen height because it's the root view in the preview.
  2. HStack(spacing: 0) — Zero spacing means no built-in gaps between children. The Spacer() is the only thing separating the two icons, which gives total control over the distribution.
  3. Spacer() in HStack — This single spacer between the two icons pushes xmark all the way to the leading edge and gear all the way to the trailing edge. This is the canonical SwiftUI navigation bar pattern.
  4. .padding(.horizontal) — Without this, the icons would sit flush against the device edges. Padding is applied to the HStack, not to the individual icons, so it creates equal insets on both sides.
  5. Spacer() in VStack — Sits between the nav bar row and the Rectangle. It expands to consume all vertical space between them, effectively pinning the rectangle to the bottom and the nav bar to the top.
  6. Rectangle().frame(height: 55) — A fixed-height bar at the bottom. This simulates a tab bar, a floating action button strip, or a send button at the bottom of a compose screen. .frame(height: 55) gives it a specific height while letting it expand to full width.

Common Mistakes

Mistake: Using Spacer outside of a Stack and getting an unexpectedly large view Outside a VStack or HStack, Spacer expands in both dimensions, potentially causing the entire screen to be occupied by an invisible view. Always use Spacer inside a stack container.

Mistake: Using Spacer to push content away from the screen edge when .padding() is the right toolSpacer creates flexible space. If you want a fixed margin between a view and the screen edge, use .padding(). Spacer is for dynamic distribution of remaining space between views, not for fixed insets.

Mistake: Using multiple Spacers expecting one to be larger than another Multiple Spacers in the same stack divide available space equally by default. There's no built-in priority for spacers — they all grow at the same rate. If you need unequal spacing, use a single Spacer plus explicit padding on one side, or .frame(height:) on a Spacer to give it a fixed size.

Key Takeaways

  • Spacer expands along its parent stack's axis, pushing all other views toward the edges
  • In HStack: one Spacer between two items creates the classic navigation bar layout (items at opposite edges)
  • In VStack: one Spacer above a view pins it to the bottom; one Spacer below pins it to the top

Last updated: June 27, 2026

Released under the MIT License.