A SwiftUI Spacer Extension

March 25, 2020

JP McGlone

As I write more SwiftUI, I am finding (or creating) new ways to help me accomplish pixel perfect parity with my designs. What do I mean?

Imagine you have a design for a user’s avatar, and right underneath their avatar is their username—exactly 10pt away.

alt text

One way I’ve seen people do this in SwiftUI is something like this:

VStack {
  Image(avatarImage)
    .padding(10, .bottom)
  Text(username)
}

I don’t like this because it is saying that the view Image has a padding under it of 10pt. Technically, this same visual effect can also be accomplished like this:

VStack {
  Image(avatarImage)
  Text(username)
    .padding(10, .top)
}

Which, again, says something different then what is indicated in the design.

Some people will force a frame on a Spacer like this:

VStack {
  Image(avatarImage)
  Spacer()
    .frame(height: 10)
  Text(username)
}

I think that’s too verbose and the Spacer API should have something cleaner.

Well, now it does! I extended Spacer to work (almost) precisely this way.

Here’s the extension:

public extension Spacer {
  static func exactly(_ value: CGFloat) -> some View {
    Spacer()
      .frame(
        width: value,
        height: value
    )
  }

  static func idealOrLess(_ value: CGFloat) -> some View {
    Spacer()
      .frame(
        idealWidth: value,
        maxWidth: value,
        idealHeight: value,
        maxHeight: value
    )
  }

  static func idealOrMore(_ value: CGFloat) -> some View {
    Spacer()
      .frame(
        minWidth: value,
        idealWidth: value,
        minHeight: value,
        idealHeight: value
    )
  }
}

And are examples of the extension being used

VStack {
  Image(avatarImage)

  // The spacing between `Image` and `Text` is `exactly` 10
  Spacer.exactly(10)

  Text(username)
}
VStack {
  Image(avatarImage)

  // The spacing between `Image` and `Text` is `exactly` 10 (or less if it can't fit)
  Spacer.idealOrLess(10)

  Text(username)
}

This reads a whole lot better.

Please give my extention a try and tell me what you think on Twitter! @SwiftGuild

And here’s a link to the extension on gist.


JP McGlone

iOS Engineer

© 2021   

Swift Guild by JP McGlone, LLC