Printed on: July 1, 2025
Up to date on: July 10, 2025
Liquid Glass is iOS 26’s new design language. Which means plenty of apps shall be adopting a brand new UI philosophy that may require some vital adjustments to the way you’re designing your app’s UI.
In case you’re not able to undertake Liquid Glass simply but, Apple has offered you an escape hatch that ought to be usable till the following main iOS launch.
I just lately explored updating my exercise app Maxine to work nicely with Liquid Glass tab bars which you’ll be able to be taught extra about right here.
On this publish, I’d prefer to discover how we are able to construct customized Liquid Glass elements for our apps operating on iOS 26 and its siblings. We’ll begin off by exploring when Liquid Glass is suitable after which transfer on to have a look at SwiftUI’s Liquid Glass associated view modifiers.
By the top of this publish, we’ll have constructed the UI which you could see in motion under (video slowed down for dramatic impact):

In case you choose studying by way of video, you may check out this publish on YouTube
When must you use Liquid Glass
The thought of Liquid Glass is that it acts as a layer on high of your app’s UI. In apply this can often imply that your most important app content material isn’t constructed utilizing the glass fashion. Doing so would lead to some fairly unhealthy trying UI as you may see on this video:

On this video, I utilized a glass impact to all of my record rows. The result’s a brilliant bizarre interface that overuses Liquid Glass.
As a substitute, Liquid Glass ought to be utilized to components that sit on high of your UI. Examples embody toolbars, tab bars, floating motion buttons and comparable elements.
An instance of this may be seen proper right here in Maxine:

The default tab bar is a Liquid Glass part that overlays my record. The floating plus button additionally has a glass impact utilized to it though you may barely see it as a result of gentle background.
The purpose is that Liquid Glass components ought to at all times be designed as sitting “on high” of one thing. They don’t stack, they’re not a part of your most important UI, they’re at all times on their very own layer once you’re designing.
Now, I’m not a designer. So should you can give you an effective way to make use of Liquid Glass that locations a component in your most important content material. I’m not going to let you know which you could’t or shouldn’t; you in all probability know a lot better than I do. That stated, Apple’s philosophy for Liquid Glass is a layered design so for security you need to in all probability follow that.
Making use of a Liquid Glass impact to UI components
Let’s construct out a pleasant UI component that may actually profit from a Liquid Glass appear and feel. It’s a UI component that existed in an app known as Path which not exists, and the UI component hasn’t actually been used a lot since. That stated, I just like the interplay and I feel it’ll be enjoyable to offer it a glass overhaul.
Our Start line
You may see an instance of the button and its UI proper right here:

It takes fairly some code to realize this impact, and most of it isn’t related to Liquid Glass. That’s why you may check out the ultimate code proper right here on GitHub. There’s a department for the start line in addition to the top consequence (most important) so you may mess around a bit should you’d like.
The view itself appears like this:
struct ContentView: View {
@State personal var isExpanded = false
var physique: some View {
ZStack(alignment: .bottomTrailing) {
Colour
.clear
.overlay(
Picture("bg_img")
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
)
button(kind: .residence)
button(kind: .write)
button(kind: .chat)
button(kind: .electronic mail)
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.background(Circle().fill(.purple))
.foregroundColor(.white)
}.padding(32)
}
}
personal func button(kind: ButtonType) -> some View {
return Button {} label: {
Label(kind.label, systemImage: kind.systemImage)
.labelStyle(.iconOnly)
.body(width: 50, peak:50)
.background(Circle().fill(.white))
}
.padding(32)
.offset(kind.offset(expanded: isExpanded)
.animation(.spring(period: kind.period, bounce: 0.2))
}
}This view by itself isn’t all that attention-grabbing, it comprises a few buttons, and making use of a liquid glass impact to our buttons shouldn’t be too laborious.
Making use of a glass impact
To make buttons appear to be Liquid Glass, you apply the glassEffect view modifier to them:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.background(Circle().fill(.purple))
.foregroundColor(.white)
}
.glassEffect()
.padding(32)After making use of the liquidGlass modifier to all buttons the app appears like this once you run it:

We’re not seeing a glass impact in any respect!
That’s as a result of we additionally set a background on our buttons, so let’s go forward and take away the background to see what our view appears like:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.glassEffect()
.padding(32)If we run the app now, our UI appears like this:

Our icons are a bit laborious to learn and I’m truthfully not precisely certain whether or not this can be a beta bug or whether or not it’s presupposed to be this fashion.
Be aware that Button additionally comes with a .glass button fashion that you need to use. This impact is barely completely different from what I’ve used right here however I discover that the button fashion doesn’t at all times enable for the sorts of customizations that I like.
You may apply the glass button fashion as follows:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.buttonStyle(.glass)
.padding(32)That stated, there are two issues I’d love to do at this level:
- Apply a background tint to the buttons
- Make the buttons seem interactive
Let’s begin with the background colour.
Making use of a background colour to our glass impact
To fashion our buttons with a background colour, we have to tint our glass. Right here’s how we are able to do this:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.glassEffect(.common.tint(.purple))
.padding(32)This already appears loads higher:

Discover that the buttons nonetheless have a round form though we’re not explicitly drawing a circle background. That’s the default fashion for elements that you just apply a glassEffect to. You’ll at all times get a form that has rounded corners that match properly with the remainder of your app’s UI and the context the place the impact is utilized.
I do really feel like my buttons are a bit too opaque, so let’s apply a little bit of opacity to our tint colour to get extra of a see-through impact:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.glassEffect(.common.tint(.purple.opacity(0.8))
.padding(32)That is what our view appears like now:

Once I faucet the buttons now, not loads occurs as proven within the video above. We will do higher by making our buttons reply to person interplay.
Making an interactive glass impact
To make our glass buttons reply to person enter by rising a bit and making use of a kind of shimmer impact, we apply the interactive modifier to the glass impact:
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.glassEffect(.common.tint(.purple.opacity(0.8).interactive())
.padding(32)That is what our interactions appear to be now:

Our UI is coming collectively. With the glassEffect view modifier, the interactive modifier and a tint we managed to construct a fairly compelling impact.
Nevertheless, our UI isn’t fairly liquid. You’re taking a look at distinct buttons performing an impact.
We will group our components collectively to make it seem as if they’re all coming from the identical drop of glass.
This sounds a bit bizarre so let’s simply leap into an instance straight away.
Grouping Liquid Glass components collectively
The very first thing we must always do now that we’ve got a bunch of components which might be all utilizing a Liquid Glass impact is group them collectively in a container. It is a suggestion from Apple that helps be sure that the system can render our results effectively. It additionally makes it in order that Liquid Glass components which might be shut collectively will begin to mix into one another. This makes it appear to be they’re all merging and seperating as they transfer across the display.
GlassEffectContainer {
button(kind: .residence)
button(kind: .write)
button(kind: .chat)
button(kind: .electronic mail)
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Label("House", systemImage: "record.bullet")
.labelStyle(.iconOnly)
.body(width: 50, peak: 50)
.foregroundColor(.white)
}
.glassEffect(.common.tint(.purple.opacity(0.8)).interactive())
.padding(32)
}By putting our Liquid Glass UI components in the identical container, the weather will mix collectively after they’re shut to one another within the UI. For instance, once we place all buttons in an HStack with no spacing, they find yourself trying like this:

As a result of all the weather are in the identical GlassEffectContainer, we are able to now run our animation and have the buttons animate in a fluid method:

I’ve slowed every part down a bit so you may benefit from the impact and see that the elements all originate from a single button, making them appear to be a liquid.
The mathematics to realize all that is a part of the ButtonType enum within the GitHub repository which you could try if you wish to see precisely how the top consequence was achieved.
In Abstract
Liquid glass won’t be your factor and that’s completely advantageous. That stated, it permits us to experiment with UI in enjoyable ways in which would possibly shock you.
On this publish, you discovered in regards to the glassEffect modifier in addition to the glassEffectID view modifier to construct a enjoyable menu part that may present and conceal itself utilizing a enjoyable, fluid animation.
If you wish to see the top consequence or use this code, be at liberty to drag it from GitHub and modify it to fit your wants.

