SwiftUI Progressive Disclosures Tutorial

Learn how to dress up your iOS apps with SwiftUI views containing progressive disclosures using state variables, animations and transitions. By Michael Katz.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Admiring SwiftUI Progressive Disclosures

The new view is now inserted by sliding down and slowly fading in, but it fades out quickly while it slides back up. By changing the duration of just the opacity, the move transition happens at the same speed as the cell expansion. Build and run again. You’ll see the animation is less jarring than before.

When a picture is clicked, the others slide down and text slides down from the clicked picture

Overall, there’s still some room to improve here, but that would require a custom transition. Check out the SwiftUI Animation course for more information on custom animations.

Showing Sheets

So far, you’ve seen views expand to fit new content that gets inserted into the hierarchy. Another common way of showing new information or controls on-screen is temporarily overlaying the content.

One tool provided by SwiftUI is a sheet. This modal view covers your main content with a new view. This is useful to present a dialog with controls or a full screen of content. In your DogLife app, a sheet presents a selection of pictures to share when the share button, mentioned above, is pressed.

The visible share sheet with some images selected

You Could Use More State

If you’re thinking that state is involved in displaying a sheet, you’re starting to understand SwiftUI. If there’s one consistent theme in SwiftUI, it’s the use of state. In the same way you used a state property to show the dog/cat picker or the breed details, you’ll again use a state property to control whether the sheet view is displayed.

This time you’ll work in RootView.swift. RootView, in this case, represents the primary — and only — window and contains the MainTable you previously modified. This is where you’ll add the sheet and its accompanying logic. While a sheet’s behavior is the same regardless of what view it’s attached to, setting it at the top gives it a clean look. In addition, since you’ll work with a global state to trigger the sheet, the root view is the view equivalent of a global since it contains all the subviews in this app.

To better understand this, add the following modifier after the closing task brace in RootView.swift:

.sheet(isPresented: $alertCenter.showShare) {
  if let animal = alertCenter.animalToShare {
    ShareSheet(animal: animal)
  }
}

alertCenter is the global state used here. It’s an environment variable, meaning a single instance of it gets passed around through the view hierarchy. showShare is set whenever the share sheet is ready for showing. Note that ShareSheet is a custom modal dialog and not the iOS built-in share sheet — see AlertCenter.swift for the custom implementation.

Viewing the State Sheet

Build and run. Now, when you tap a cell, tap the share icon in the expanded detail view. This brings up a sheet where you can select some images to send to a friend.

The visible share sheet with some images selected

It’s worth further explaining how this works, since the action is decoupled from the view changes:

  1. In ShortDetails.swift, the button action alertCenter.animalToShare = animal updates the animalToShare value.
  2. In AlertCenter, the animalToShare‘s didSet updates the showShare property.
  3. Since showShare is Published, it sends an update to all its listeners.
  4. Because RootView is using AlertCenter as an @EnvironmentObject, it’s listening for changes.
  5. The sheet is using showShare as the control for isPresented in RootView. When that changes, the modified view modally presents the sheet.
  6. The send button on the share sheet will set showShare to false by setting animalToShare to nil — see the button code in ShareSheet.swift. Dismissing the view by sliding it down also sets showShare to false through the sheet’s built-in behavior.

All you have to do here is update the state, and sheet takes care of its display and dismissal. This makes it an easy way to get a view on-screen. However, you can only have one active sheet at a time. If your sheets need to disclose more views, you’ll either have to insert them into your sheet or use a navigation view to push more views onto the sheet.

Adding Toast Views

Now that you’re one “sheet” to the wind, you can “toast” for more SwiftUI progressive disclosures. In particular, you can display views on top of your content by inserting them into the view hierarchy instead of presenting them as a modal dialog. This is useful for temporary banners, a custom modal, or a popup or tooltip. Basically, this is a good technique to use anytime you want to temporarily display a message to the user.

A view popping up from the bottom — or top — of the screen is sometimes called a toast. The view gets its name because it’s like a piece of bread ejected upward from an old-timey toaster. In DogLife, you can use a toast view to show status to the user, such as displaying a successful sharing of photos.

DogLife app showing the toast message at the bottom of the screen

Conditionally Displaying a View in a ZStack

In SwiftUI, ZStack views let you arrange views on top of each other. It’s useful here, as it allows the toast view to slide up over the main content. Looking at RootView.swift, MainTable is already wrapped in ZStack. Now, add the following below MainTable() but still inside ZStack:

// 1
if alertCenter.showToast {
  // 2
  alertCenter.buildToast()
    // 3
    .transition(.move(edge: .bottom))
}

This code reuses patterns you’ve seen above:

  1. showToast lets the view conditionally add the toast to the hierarchy. This is a published value of alertCenter, so the view will automatically update when it changes.
  2. buildToast() is a helper method that returns the view with the user message.
  3. As you’ve already seen, a move transition will slide the view into the scene, in this case from the bottom.

Seeing Your Toast in Action

The share button is already wired up to trigger the toast message, so when you build and run, you can make some toast. To do that, tap a dog breed to display both the detailed text and the share button. Then, tap the share button, tap one or more photos presented on the sheet and then tap Send. The toast then slides up and shows the message at the bottom of the screen. Tapping the x button hides the toast view again through the same move transition you added in the third step above.

DogLife app showing the toast message at the bottom of the screen