SwiftUI Views & Layouts

Jun 20 2024 · Swift 5.10, iOS 17.4, Xcode 15.3

Lesson 02: Configuring Layouts

Demo 2

Episode complete

Play next episode

Next
Transcript

Now that you know about Device size classes, you can start improving the UI by changing the layout to better use the available space in landscape orientation.

Instead of allowing users to scroll the content, you’ll move the views around so they fit on screen, no matter the orientation. When the device is in landscape, the title and color rectangle will be on the left and the sliders and button on the right.

But first, to do that, you’ll read the horizontal and vertical size classes from the environment to determine the available space on screen.

Open ContentView.swift and add the following code after the @State variable declarations:

@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Environment(\.verticalSizeClass) var verticalSizeClass

The first property is reading the horizontal size class from the environment. And, the second property is reading the vertical one.

Next, you’ll create a computed boolean property to track the available space to screen and decide which layout to use. Add the following code under the two environment properties you just added:

var landscapeIsCompact: Bool {
  horizontalSizeClass == .compact && verticalSizeClass == .compact ||
    horizontalSizeClass == .regular && verticalSizeClass == .compact
}

The first part of this computed property is checking if the horizontal and vertical size classes are both .compact. That happens when an iPhone 15 Pro or smaller device is in landscape orientation. The second part checks if the horizontal size class is .regular and the vertical size class is .compact. That would be the case of an iPhone 15 Pro Max or iPhone 15 Plus on landscape orientation.

If either of those two conditions are true, you’ll change the UI to use a HStack instead of a VStack.

But before you do that, much like in the previous lesson, you’re going to create new custom views to help you reuse code when changing between a vertical layout and a horizontal layout.

Create a new SwiftUI file and name it RGBSlidersStackView.swift. Next, add the following binding properties:

@Binding var color: Color
@Binding var red: Double
@Binding var green: Double
@Binding var blue: Double

You’ll bind these properties and change the values of the sliders and color of the rectangle.

Next, replace the contents of the body with the following code:

VStack {
  RGBSliderView(rgbSlider: .red, value: $red)
  RGBSliderView(rgbSlider: .green, value: $green)
  RGBSliderView(rgbSlider: .blue, value: $blue)

  Button("Set Color") {
    color = Color(
      red: red / 255,
      green: green / 255,
      blue: blue / 255
    )
  }
  .primaryBackground()
}

This extracts the code of the three sliders and the button to set the color to the body of this new view.

Before you move on, you’ll update the preview of this view. Replace the code inside the preview macro with the following:

RGBSlidersStackView(
  color: .constant(.red),
  red: .constant(50),
  green: .constant(50),
  blue: .constant(50)
)
.padding()

Ok! Now you’re ready to use the new view in ContentView.swift.

Back inside ContentView.swift, replace the contents of the body property with the following:

Group {
  if landscapeIsCompact {
    HStack(spacing: 16) {
      ColorCardView(color: color)

      RGBSlidersStackView(
        color: $color,
        red: $red,
        green: $green,
        blue: $blue
      )
    }
  } else {
    VStack(spacing: 16) {
      ColorCardView(color: color)

      RGBSlidersStackView(
        color: $color,
        red: $red,
        green: $green,
        blue: $blue
      )
    }
  }
}
.padding()

Here, you’re using a HStack when landscapeIsCompact is true and a VStack when its false.

Build and run the project. Rotate the screen by clicking the top right button at the top of the window of the simulator to check the layout in landscape too.

The view now arranges its views horizontally when in landscape orientation, and vertically when in portrait orientation. When you rotate the device, landscapeIsCompact changes and you use the correct layout. Good job!

See forum comments
Cinema mode Download course materials from Github
Previous: Instruction 2 Next: Conclusion