Instruction
With Liquid Glass being a brand new design system, Apple is keen for developers to adopt it. Adoption helps Apple demonstrate the design system is a success, and so they’re doing everything they can to make it easy for you as a developer to implement it.
You saw this approach in the first lesson, where by just building the Cards app for iOS 26, the app upgraded to use Liquid Glass with no code changes. Apple provide other ways to make the adoption as easy as possible too. They’ve created an entire page in their documentation on how to adopt Liquid Glass into your apps using best practices.
For this lesson, you’ll continue to work on the Cards app from lesson 1. You’ll apply these best practices to the app, giving you an opportunity to get familiar with Liquid Glass. You’ll also get a feel going through the process of transitioning an app from flat design into Liquid Glass.
Leveraging System Frameworks
Open the Starter project for this lesson, and build the app using an iOS 26 device or simulator. Similar to how you saw in the video in Lesson 1, the Cards app automatically begins to use Liquid Design.
This is because the System Frameworks, such as SwiftUI, have been built to adopt Liquid Design. This is a big benefit provided by Apple, it means you don’t need to worry about making design changes to standard controls. In classic Apple Fashion, it just works!
If you happen to be working on an older app which still use UIKit controls. Liquid Glass is also applied to these controls. One less worry to think about!
This is the first best practice to keep in mind. If you make sure to use the system frameworks whilst building the UI in your app, the majority of the hard work will be done for you!
Reviewing Your App Controls
Now that the Cards app is using Liquid Glass, the next step is to review it to ensure there are no bugs within the controls. Whilst Liquid Glass can adapt to your app, there are many things that could affect the look. Let’s look at an example.
Take a moment to review the Cards app UI and see if you spot anything odd. Ignore the settings button for now, you’ll change this later.
You may notice that the BottomToolbar view shown as part of the CardToolbar modifier in SingleCardView.swift looks a bit tight packed.
This is one of the issues you may find in your own apps. UI Controls may easily adopt the new design, but there could be issues with the size of the control, or even how images fit within the control.
Apple recommend that Liquid Glass controls should have enough space to “move and breathe” and to avoid overcrowding. This control doesn’t seem to have much room to breathe, so let’s fix that.
Open BottomToolbar.swift and add a .padding() modifier to the end of the HStack inside the body function:
struct BottomToolbar: View {
@EnvironmentObject var store: CardStore
@Binding var card: Card
@Binding var modal: ToolbarSelection?
var body: some View {
HStack(alignment: .bottom) {
ForEach(ToolbarSelection.allCases) { selection in
switch selection {
case .photoModal:
Button {
} label: {
PhotosModal(card: $card)
}
case .frameModal:
defaultButton(selection)
.disabled(
store.selectedElement == nil
|| !(store.selectedElement is ImageElement))
default:
defaultButton(selection)
}
}
}.padding(10)
}
... more code below ...
}
Build and run the app again, then tap on a card to show the single card view. Your toolbar now looks more comfortable with the added padding. Phew!
This is a good example of another best practice when adopting Liquid Glass. Ensure your controls look good and fit with the use of Liquid Glass. If they look out of place, address it until the control looks comfortable!
Next, let’s take a look at improving the Cards app by making more use of Menus and Toolbars.
Menus & Toolbars
Menus and Toolbars received a significant update in Liquid Glass. Now instead of sitting in a bar, menus and toolbars take up less space. Meaning your content can take up more of the screen space.
You can see this in action in the SingleCardView screen you just updated in the previous section.
The app could benefit from increased screen space by using more toolbars, especially in the CardsListView screen. If you look at the screen now you’ll see the two buttons stacked on top of each other.
This would be a good opportunity to free up some screen space by using a toolbar. Let’s update the app to do that.
Open CardsListView and wrap the createButton and settingsButton inside a .toolbar.
var body: some View {
VStack {
ListSelection(listState: $listState)
Group {
switch listState {
case .list:
list
case .carousel:
Carousel(selectedCard: $selectedCard)
}
}
.overlay {
if store.cards.isEmpty {
ContentUnavailableView {
initialView
} description: {
Text("Tap the plus button to add a card")
}
}
}
.fullScreenCover(item: $selectedCard) { card in
if let index = store.index(for: card) {
SingleCardView(card: $store.cards[index])
.navigationTransition(
.zoom(
sourceID: card.id,
in: namespace))
.interactiveDismissDisabled(true)
} else {
fatalError("Unable to locate selected card")
}
}.toolbar { // Add the toolbar here
ToolbarSpacer(.flexible, placement: .bottomBar)
ToolbarItemGroup(placement: .bottomBar) {
createButton
settingsButton
}
}
}
.background(Color.background.ignoresSafeArea())
}
Inside the toolbar, you add a ToolbarSpacer, this is a new API in iOS 26, providing the ability to control the amount of space inside the toolbar. You also add ToolbarItemGroup to hold the create button and settings button.
Build and run the app again, and take a look at the difference.
The stack has been cleaned up, and the Liquid Glass is providing a minimal toolbar that floats above the content! The toolbar spacer is also pushing the content to the right of the screen. Much better!
You may notice the items have shifted to showing just the icons, and appear to be grouped together. This is another change with Liquid Glass, where icons and groupings become important.
The best practice says make use of icons that are standard to uses. Applying that practice in the context of the Cards App, using the plus icon and the settings icon provide recognizable actions to users.
Finally, grouping toolbar actions together in a way that makes sense is important to create a sense of consistency to your user. Since apps original controls here were both present, it makes sense to group both of these actions together. You may decide to group actions in a different way, the main takeaway is to make sure your groupings are consistent across the app.
Let’s move onto the next section, and look at how list based layouts adapt to Liquid Glass.
List Based Layouts
List based layouts have been a staple in iOS development for many years. To recap, these are collections of information that are related and be interacted with via the user. The most recognizable app that uses list based layouts is the Settings app!
For the purpose of demonstrating how list based layouts, the Cards App has had a settings screen added. You can see this screen by tapping on the settings icon in the toolbar you added in the earlier section.
If you open the SettingsView.swift file, you’ll that all the code is using SwiftUI Forms. This is another example of System Framework controls automatically picking up the Liquid Glass changes for iOS 26.
Take a moment to interact with the screen and notice the behavior changes that the list provides with Liquid Glass. The most obvious thing is how the dropdown for the background appear is bigger, taking up more space. In the flat design style this was more minimal, and took less space.
You may also notice the toggle also takes up more room, and is bigger. Similar to the flat design style, the picker takes up less space and is smaller.
Take a moment to compare the two simulators below, each running the app in different design languages. See how Liquid Glass provides a more open and bold approach.
In the next and final section, you’ll learn about a handy way to forcibly disable Liquid Glass for your app.
Compatibility Mode
You may be a developer who is working on a large app where adjusting to Liquid Glass just isn’t feasible before the official release of iOS 26. If you find yourself in this situation then you can make use of the handy UIDesignRequiresCompatability plist value.
This value enables your app to be built using the latest SDKs, whilst also retaining the flat design look available in previous versions of iOS.
To add it, open the app Info.plist and add the following key, UIDesignRequiresCompatability. Ensure the type is a Boolean and set it to YES.
Build and run the app using an iOS 26 device. You should notice all traces of Liquid Glass has disappeared!