Padding in SwiftUI: A Comprehensive Guide

There are plenty of ways to approach spacing in your SwiftUI views. You can use the Spacer() to align elements to the left or right or fill up the space between them, or you can set the value of the spacing property in your HStacks or VStacks to distribute their child views according to your (or your designer's) preferences.

But all those fancy layout options pale in comparison to good old padding. I don't know about you, but for me, padding is by far the most frequently used ViewModifier. So, having a solid understanding of its capabilities is crucial.

Apologies for the long intro for such a simple feature. Padding(ton) bear with me. We're just about to get started.


Basic Padding

All you need to do to add some padding to your view is to apply the .padding() ViewModifier to any kind of view.

Text("Hello, SwiftUI!").padding()

When providing no further information, SwiftUI will decide how much padding you actually get. Depending on the platform and nesting of your view, some default value will be applied to all four sides of the view. It doesn't get any simpler than that, so let's make it more complicated by adding a concrete value to it.

Text("Hello, SwiftUI!").padding(20)

Adding a concrete value makes you lose the automatic behavior, but provides much more control. And this is what we wanted. So let's go further by applying multiple padding values to one view. Additionally, you can use negative padding values to create overlapping views or interesting visual effects in certain design scenarios.

// Only adds padding to the top (default padding)
Text("Hello, SwiftUI!").padding(.top)

// Only adds padding to the bottom (positive value)
Text("Hello, SwiftUI!").padding(.bottom. 20)

// Only adds leading padding (default padding)
Text("Hello, SwiftUI!").padding(.leading)

// Only adds trailing padding (negative value)
Text("Hello, SwiftUI!").padding(.trailing. -20)

// Adds leading and trailing padding (default padding)
Text("Hello, SwiftUI!").padding(.horizontal)

// Adds top and bottom padding (positive value)
Text("Hello, SwiftUI!").padding(.vertical. 20)

Neat! In addition to this, you can also chain multiple .padding()ViewModifiers to create even more custom designs. Keep in mind the order of modifiers in SwiftUI, particularly when it comes to padding and other layout modifiers (e.g., background color, border). The order in which padding is applied relative to other modifiers can affect the appearance and layout of views.

// Adds the same padding to the leading, trailing and bottom edges
Text("Hello, SwiftUI!")
	.padding([.horizontal, bottom], 10)
    
 // Adds different trailing and top padding
 Text("Hello, SwiftUI!")
	.padding(.top, 10)
    .padding(.trailing, 20)

Different Padding on All Four Sides

As you can see, we have all the options, but it can get a bit cumbersome when, let's say, you need different padding values on all four sides.

// Adds different padding values to all four sides
Text("Hello, SwiftUI!")
	.padding(.top, 20)
    .padding(.bottom, 10)
    .padding(.leading, 5)
    .padding(.trailing, 15)

For this case we can write a simple Extension of View

extension View {
    func padding(_ edgeLengths: [Edge.Set: CGFloat]) -> some View {
        var modifiedView = self
        
        for (edge, length) in edgeLengths {
            modifiedView = modifiedView.padding(edge, length)
        }
        
        return modifiedView
    }
}

Which can then be used like this:

Text("Hello, SwiftUI!")
	.padding([
		.leading: 20,
		.trailing: 40,
		.top: 10,
		.bottom: 30
	])

Cool! Not much more to say about .padding(), I guess. I hope all the above will help you give your views the space they deserve.

XOXO, Christian 👨🏻‍💻