SwiftUI Max Width and Frame Alignment: Aligning Elements Using HStack and Spacer()

This tutorial will explain how to align elements in SwiftUI using HStack and Spacer. HStack is a container that arranges its child views horizontally, and Spacer is a flexible empty view that takes up all the remaining space in its parent container. By combining these two views, you can create layouts that are both flexible and aligned. 

In addition, this tutorial will also cover how to set a maximum width for your views, and how to align your views within their frames.

However, this can necessitate too many containers, especially if you want to align to the top left or top right. 

An alternative is to use the frame modifier with maxWidth and alignment.

An alternative to stacks and spacer is to use frame max width and alignment to avoid the pyramid of doom

Definition : In computer programming, the pyramid of doom is a common problem that arises when a program uses many levels of nested indentation to control access to a function. It is commonly seen when checking for null pointers or handling callbacks. 

 

Stacks and Spacer Alternatives 

  • Let's take a common example of a floating close button that we want to align to the far top right of the screen. 
  • This creates requires a VStack and an HStack, plus two Spacer(). 
  • When you have too many containers, you will likely create a pyramid of doom, which is not ideal for readability and maintenance. 

VStack {
	HStack {
		Image(systemName: "xmark")
			.frame(width: 35, height: 32)
			.background(Circle().stroke())
		Spacer()
	}
	Spacer()
}
.padding()

..

Max Width and Alignment  

By using a frame modifier with maxWidth and maxHeight set to infinity, and alignment set to topTrailing, you get the same result.

Image(systemName: "xmark")
	.frame(width: 32, height: 32)
	.background(Circle().stroke())
	.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
	.padding()

..

Overlay  

The floating close button can be put in an overlay modifier which put the element above the content.

Rectangle()
    .fill(Color.blue)
    .overlay(
        Image(systemName: "xmark")
            .frame(width: 32, height: 32)
            .background(Circle().stroke())
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
            .padding()
    )

..


Comments