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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
SwiftUI Progressive Disclosures Tutorial
25 mins
- Getting Started
- Inserting a View in SwiftUI
- Adding a State Property to Track Selections
- Inserting a Picker Control View
- Adding Another State property to Track Visibility
- Animating SwiftUI Progressive Disclosures
- Adding SwiftUI Progressive Disclosures to a Cell
- Adding Another State Property to Track Cell Selection
- Conditionally Adding a New View
- Adding a Gesture to Trigger the View
- Adding Animations to Improve the User Experience
- Adding Transitions for More Customization
- Matching Transitions to Animations
- Combining Animations and Transitions in SwiftUI
- Admiring SwiftUI Progressive Disclosures
- Showing Sheets
- You Could Use More State
- Viewing the State Sheet
- Adding Toast Views
- Conditionally Displaying a View in a ZStack
- Seeing Your Toast in Action
- Where to Go From Here?
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.
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.
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.
It’s worth further explaining how this works, since the action is decoupled from the view changes:
- In ShortDetails.swift, the button action
alertCenter.animalToShare = animal
updates theanimalToShare
value. - In
AlertCenter
, theanimalToShare
‘sdidSet
updates theshowShare
property. - Since
showShare
isPublished
, it sends an update to all its listeners. - Because
RootView
is usingAlertCenter
as an@EnvironmentObject
, it’s listening for changes. - The
sheet
is usingshowShare
as the control forisPresented
inRootView
. When that changes, the modified view modally presents the sheet. - The send button on the share sheet will set
showShare
tofalse
by settinganimalToShare
tonil
— see the button code in ShareSheet.swift. Dismissing the view by sliding it down also setsshowShare
tofalse
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.
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:
-
showToast
lets the view conditionally add the toast to the hierarchy. This is apublished
value ofalertCenter
, so the view will automatically update when it changes. -
buildToast()
is a helper method that returns the view with the user message. - 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.