Pendahuluan: Revolusi Desain Terbesar Apple Sejak iOS 7
Kalau kamu mengikuti perkembangan dunia iOS development, pasti sudah dengar soal Liquid Glass — bahasa desain baru Apple yang diperkenalkan di WWDC 2025. Dan jujur, ini bukan sekadar update kosmetik biasa. Liquid Glass sekarang jadi fondasi utama tampilan iOS 26, dan bisa dibilang ini perubahan desain paling signifikan sejak flat design era iOS 7.
Sebagai developer, kamu wajib memahaminya. Titik.
Jadi, apa sebenarnya Liquid Glass itu? Singkatnya, ia menggabungkan sifat optik kaca — refraksi, refleksi, efek lensa — dengan fluiditas cairan. Hasilnya adalah material yang transparan, dinamis, dan bereaksi terhadap konten di belakangnya secara real-time. Elemen UI yang pakai Liquid Glass akan terasa "hidup" karena mereka berubah mengikuti warna, cahaya, bahkan gerakan perangkat. Keren banget kalau dilihat langsung di device.
Yang lebih menarik lagi, Liquid Glass bukan cuma untuk iOS 26. Desain ini seragam di seluruh ekosistem Apple — iPadOS 26, macOS Tahoe, watchOS 26, tvOS 26, dan visionOS 26. Jadi sekali kamu paham konsepnya, tinggal terapkan ke semua platform.
Dalam panduan ini, kita akan bahas tuntas cara implementasi Liquid Glass di SwiftUI — mulai dari modifier dasar glassEffect(), berbagai style dan shape, teknik tinting, penggunaan GlassEffectContainer untuk efek morphing, sampai best practices dan aksesibilitas. Semua dilengkapi contoh kode yang bisa langsung kamu coba di Xcode 26. Yuk, langsung mulai.
Persyaratan dan Persiapan
Sebelum mulai ngoding, pastikan environment kamu sudah siap. Ini checklist-nya:
- Xcode 26 atau lebih baru
- iOS 26 SDK (atau platform 26 lainnya)
- Perangkat fisik atau Simulator yang menjalankan iOS 26+
- Deployment target: iOS 26.0 minimum
Catatan penting: API Liquid Glass seperti glassEffect() hanya tersedia di iOS 26 ke atas. Kalau kamu menargetkan iOS versi lama, kode yang pakai API ini nggak akan bisa dikompilasi. Pastikan kamu menggunakan #available check kalau aplikasimu perlu support versi iOS sebelumnya.
Memahami Konsep Dasar Liquid Glass
Oke, sebelum loncat ke kode, penting banget untuk memahami filosofi desain di balik Liquid Glass dulu. Ini bakal membantu kamu mengambil keputusan yang tepat saat implementasi nanti.
Kapan Menggunakan Liquid Glass
Liquid Glass dirancang secara eksklusif untuk lapisan navigasi — elemen-elemen yang "mengapung" di atas konten utama aplikasi. Contohnya:
- Toolbar dan navigation bar
- Tab bar
- Floating action button
- Kontrol overlay dan panel samping
- Tombol aksi yang melayang di atas konten
Kapan TIDAK Menggunakan Liquid Glass
Ini yang sering bikin developer baru tergoda. Jangan pernah menerapkan Liquid Glass pada konten utama — seperti sel list, tabel, kartu konten, atau media. Menerapkan glass effect ke semua row dalam list bakal menghasilkan interface yang aneh dan justru merusak pengalaman pengguna. Ingat prinsip utamanya:
Elemen Liquid Glass harus selalu dirancang seolah-olah mereka "duduk di atas" sesuatu. Mereka tidak boleh jadi bagian dari konten utama UI — mereka selalu berada di lapisan tersendiri.
Kalau kamu ragu apakah suatu elemen perlu glass effect atau tidak, tanya ke diri sendiri: "Apakah elemen ini mengapung di atas konten?" Kalau jawabannya tidak, skip glass effect.
Modifier glassEffect(): Dasar dari Segalanya
Nah, sekarang mari kita masuk ke hal yang paling fundamental — modifier glassEffect(). Ini satu-satunya modifier yang kamu butuhkan untuk menambahkan efek Liquid Glass ke view apapun di SwiftUI.
Implementasi Paling Sederhana
Cukup satu baris kode. Serius, cuma satu baris:
import SwiftUI
struct BasicGlassView: View {
var body: some View {
Text("Hello, Liquid Glass!")
.padding()
.glassEffect()
}
}
Secara default, glassEffect() menerapkan style regular dengan bentuk capsule di belakang konten view. Hasilnya langsung terlihat — teks kamu dibungkus material transparan yang memantulkan dan membiaskan konten di belakangnya. Simpel tapi efeknya langsung terasa.
Hal Penting yang Harus Diingat
Glass effect bukan sekadar background biasa. Ini perbedaan yang krusial. Ia berinteraksi secara aktif dengan view di belakangnya dan bisa mengubah propertinya secara dinamis. Yang cukup mengejutkan, glass effect bahkan bisa mengubah color scheme view kamu dari light ke dark (atau sebaliknya) tergantung konten di belakangnya. Ini sangat berbeda dari modifier .background() biasa yang sifatnya statis.
Oh iya, satu hal lagi — kalau view kamu sudah punya modifier .background(), hapus dulu sebelum menambahkan .glassEffect(). Background yang solid akan memblokir efek glass sehingga nggak terlihat. Ini sering jadi sumber kebingungan buat yang baru coba.
Tiga Gaya Glass: Regular, Clear, dan Identity
SwiftUI menyediakan tiga instance predefined dari tipe Glass, masing-masing punya kegunaan yang berbeda. Kita bahas satu per satu.
Regular — Gaya Default
Ini gaya yang paling umum dan paling sering kamu pakai. Material transparan dengan blur dan refraksi standar:
Text("Regular Glass")
.padding()
.glassEffect(.regular)
Gunakan .regular untuk sebagian besar elemen navigasi dan kontrol overlay. Memberikan keseimbangan yang pas antara transparansi dan keterbacaan.
Clear — Transparansi Lebih Tinggi
Gaya clear menawarkan transparansi yang lebih tinggi. Cocok banget untuk situasi di mana kamu ingin konten di belakang tetap terlihat jelas:
Text("Clear Glass")
.padding()
.glassEffect(.clear)
Pilih .clear untuk overlay yang perlu mempertahankan visibilitas konten di bawahnya — misalnya label informasi yang melayang di atas gambar.
Identity — Menonaktifkan Efek
Gaya identity ini agak unik. Secara efektif ia menonaktifkan efek glass sambil tetap mempertahankan layout. Sangat berguna untuk toggle kondisional:
@State private var isGlassEnabled = true
Text("Conditional Glass")
.padding()
.glassEffect(isGlassEnabled ? .regular : .identity)
Kenapa pakai .identity dan bukan menghilangkan modifier sepenuhnya? Karena dengan .identity, layout tetap konsisten dan nggak terjadi pergeseran posisi saat efek diaktifkan atau dinonaktifkan. Detail kecil, tapi penting untuk UX yang smooth.
Kustomisasi Bentuk (Shape)
Secara default, glass effect menggunakan bentuk capsule. Tapi kamu bebas menggantinya dengan bentuk apapun yang conform ke protocol Shape:
// Capsule (default)
.glassEffect(.regular, in: .capsule)
// Lingkaran
.glassEffect(.regular, in: .circle)
// Rounded Rectangle dengan corner radius kustom
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 16))
// Persegi panjang biasa
.glassEffect(.regular, in: .rect)
// Corner radius yang mengikuti container
.glassEffect(.regular, in: .rect(cornerRadius: .containerConcentric))
Opsi .containerConcentric ini favorit saya pribadi — ia secara otomatis menyelaraskan corner radius dengan container di sekitarnya, menghasilkan tampilan yang lebih harmonis. Nggak perlu lagi hitung-hitungan manual buat corner radius yang "pas".
Contoh Praktis: Glass Card
struct GlassCard: View {
let title: String
let subtitle: String
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(title)
.font(.headline)
Text(subtitle)
.font(.subheadline)
.foregroundStyle(.secondary)
}
.padding()
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 20))
}
}
Tinting: Memberikan Warna pada Glass
Mau kasih sentuhan warna pada material glass? Pakai fungsi tint(). Warna tint akan berbaur dengan glass sambil tetap mempertahankan sifat transparan dan blur-nya:
// Tint biru
.glassEffect(.regular.tint(.blue))
// Tint merah dengan opacity rendah — lebih subtle
.glassEffect(.regular.tint(.red.opacity(0.4)))
// Tint ungu pada clear glass
.glassEffect(.clear.tint(.purple))
// Kombinasi tint dengan opacity untuk efek halus
.glassEffect(.regular.tint(.purple.opacity(0.8)))
Catatan penting: Gunakan tint hanya untuk menyampaikan makna, bukan sekadar dekorasi visual. Sama seperti tombol toolbar yang di-tint, warna harus punya tujuan — merah untuk tindakan destruktif, biru untuk tindakan utama, hijau untuk konfirmasi. Tint yang pakai vibrant color akan beradaptasi dengan konten di belakangnya secara otomatis, jadi hasilnya selalu terlihat bagus.
Interactive Mode: Glass yang Responsif
Nah, ini fitur yang bikin glass terasa benar-benar "hidup". Modifier interactive() membuat glass lebih responsif terhadap interaksi pengguna — ia bereaksi lebih agresif terhadap konten di belakang dan menangani gesture seperti tap dan drag:
// Glass interaktif dasar
.glassEffect(.regular.interactive())
// Kombinasi lengkap: style + tint + interactive
.glassEffect(.regular.tint(.blue.opacity(0.7)).interactive())
Saat pengguna menekan elemen dengan glass interaktif, efek visual berupa shimmer dan sedikit pembesaran akan muncul. Feedback taktil yang halus ini bikin elemen terasa premium. Sangat cocok untuk tombol dan elemen yang bisa di-tap.
Contoh: Tombol Aksi dengan Glass Interaktif
struct GlassActionButton: View {
let icon: String
let action: () -> Void
var body: some View {
Button(action: action) {
Image(systemName: icon)
.font(.title2)
.foregroundColor(.white)
.frame(width: 50, height: 50)
}
.glassEffect(.regular.tint(.blue.opacity(0.6)).interactive())
}
}
// Penggunaan
GlassActionButton(icon: "plus") {
print("Tambah item baru")
}
Alternatif lain, kamu juga bisa pakai button style bawaan:
Button("Simpan") {
// aksi simpan
}
.buttonStyle(.glass)
Tapi perlu dicatat, .buttonStyle(.glass) menawarkan visual yang sedikit berbeda dan fleksibilitas kustomisasinya lebih terbatas dibanding menggunakan modifier .glassEffect() langsung. Untuk kebanyakan kasus, saya lebih prefer pakai .glassEffect() karena kontrol yang lebih granular.
GlassEffectContainer: Mengelompokkan Elemen Glass
Ini dia fitur yang bikin Liquid Glass benar-benar "liquid". GlassEffectContainer mengelompokkan beberapa elemen glass sehingga mereka bisa berinteraksi satu sama lain — berbagi specular highlight, menggabungkan batas refraksi, dan yang paling keren: morphing antar elemen.
Mengapa Perlu GlassEffectContainer?
Tanpa container, setiap elemen glass dirender secara independen. Mereka nggak saling "sadar" satu sama lain. Dengan GlassEffectContainer, kamu dapat dua manfaat utama:
- Rendering yang lebih efisien — sistem bisa mengoptimalkan proses rendering
- Fluid morphing — elemen-elemen yang berdekatan akan berbaur dan bergabung secara visual
Honestly, begitu kamu lihat efek morphing-nya secara langsung di device, kamu bakal paham kenapa container ini penting.
Implementasi Dasar
struct GlassToolbar: View {
var body: some View {
GlassEffectContainer {
HStack(spacing: 12) {
Button(action: {}) {
Image(systemName: "play.fill")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive())
Button(action: {}) {
Image(systemName: "pause.fill")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive())
Button(action: {}) {
Image(systemName: "stop.fill")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive())
}
.foregroundColor(.white)
}
}
}
Saat tiga tombol ini berdekatan di dalam container yang sama, efek glass mereka bakal berbaur satu sama lain. Hasilnya tampilan yang kohesif dan fluid — bukan tiga glass terpisah, tapi satu kesatuan visual yang menyatu.
Morphing dengan glassEffectID
Fitur morphing ini menurut saya yang paling impressive dari Liquid Glass. Ia memungkinkan glass untuk bertransisi secara mulus antar state. Dengan glassEffectID(), kamu bisa bikin animasi di mana bentuk glass berubah dari satu view ke view lain — konsepnya mirip matchedGeometryEffect, tapi khusus untuk Liquid Glass.
Cara Kerjanya
struct MorphingGlassDemo: View {
@State private var isExpanded = false
@Namespace private var glassNamespace
var body: some View {
ZStack(alignment: .bottomTrailing) {
// Background konten
Image("landscape")
.resizable()
.scaledToFill()
.ignoresSafeArea()
GlassEffectContainer {
if isExpanded {
// State expanded: tampilkan menu
VStack(spacing: 12) {
glassButton(icon: "house.fill", label: "Beranda")
glassButton(icon: "pencil", label: "Tulis")
glassButton(icon: "bubble.left.fill", label: "Pesan")
glassButton(icon: "envelope.fill", label: "Email")
}
.transition(.scale.combined(with: .opacity))
// Tombol toggle
Button {
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
isExpanded.toggle()
}
} label: {
Image(systemName: "xmark")
.font(.title2)
.foregroundColor(.white)
.frame(width: 56, height: 56)
}
.glassEffect(
.regular.tint(.red.opacity(0.6)).interactive()
)
.glassEffectID("toggleButton", in: glassNamespace)
.padding(24)
} else {
// State collapsed: hanya tombol FAB
Button {
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
isExpanded.toggle()
}
} label: {
Image(systemName: "plus")
.font(.title2)
.foregroundColor(.white)
.frame(width: 56, height: 56)
}
.glassEffect(
.regular.tint(.blue.opacity(0.7)).interactive()
)
.glassEffectID("toggleButton", in: glassNamespace)
.padding(24)
}
}
}
}
private func glassButton(icon: String, label: String) -> some View {
Button(action: {}) {
Label(label, systemImage: icon)
.frame(width: 140, height: 44)
.foregroundColor(.white)
}
.glassEffect(.regular.interactive())
}
}
Perhatikan bahwa kedua state menggunakan glassEffectID yang sama ("toggleButton") dalam namespace yang sama. Ini memberitahu SwiftUI bahwa kedua view tersebut secara konseptual adalah elemen yang sama, sehingga sistem bisa generate animasi morphing yang mulus saat transisi.
Hasilnya? Saat pengguna tap tombol FAB, bentuk glass bertransformasi secara fluid dari tombol plus biru menjadi tombol close merah, sementara menu item muncul dengan animasi yang halus. Coba sendiri — efeknya sangat satisfying.
Contoh Proyek Lengkap: Floating Player Controls
Oke, sekarang kita gabungkan semua konsep yang sudah dipelajari ke dalam satu contoh yang lebih realistis — kontrol pemutar musik yang melayang di atas artwork album. Ini contoh yang cukup mendekati use case di dunia nyata.
struct FloatingPlayerView: View {
@State private var isPlaying = false
@State private var showDetails = false
@Namespace private var playerNamespace
var body: some View {
ZStack {
// Album artwork sebagai background
Image("album-cover")
.resizable()
.scaledToFill()
.ignoresSafeArea()
VStack {
Spacer()
GlassEffectContainer {
if showDetails {
// Expanded player
VStack(spacing: 16) {
Text("Judul Lagu")
.font(.title2)
.fontWeight(.bold)
Text("Nama Artis")
.font(.subheadline)
.foregroundStyle(.secondary)
// Progress bar
ProgressView(value: 0.35)
.tint(.white)
HStack {
Text("1:23")
.font(.caption)
Spacer()
Text("3:45")
.font(.caption)
}
.foregroundStyle(.secondary)
// Kontrol
HStack(spacing: 32) {
Button(action: {}) {
Image(systemName: "backward.fill")
.font(.title2)
}
Button {
isPlaying.toggle()
} label: {
Image(systemName: isPlaying
? "pause.fill" : "play.fill")
.font(.title)
.frame(width: 60, height: 60)
}
.glassEffect(
.regular.tint(.blue.opacity(0.5))
.interactive(),
in: .circle
)
.contentTransition(.symbolEffect(.replace))
Button(action: {}) {
Image(systemName: "forward.fill")
.font(.title2)
}
}
.foregroundColor(.white)
}
.padding(24)
.glassEffect(
.regular,
in: RoundedRectangle(cornerRadius: 28)
)
.glassEffectID("playerCard", in: playerNamespace)
.onTapGesture {
withAnimation(.spring(duration: 0.5, bounce: 0.15)) {
showDetails = false
}
}
.padding(.horizontal, 16)
.padding(.bottom, 32)
} else {
// Mini player
HStack(spacing: 12) {
Image("album-thumb")
.resizable()
.frame(width: 40, height: 40)
.clipShape(RoundedRectangle(cornerRadius: 8))
VStack(alignment: .leading) {
Text("Judul Lagu")
.font(.subheadline)
.fontWeight(.medium)
Text("Nama Artis")
.font(.caption)
.foregroundStyle(.secondary)
}
Spacer()
Button {
isPlaying.toggle()
} label: {
Image(systemName: isPlaying
? "pause.fill" : "play.fill")
.font(.title3)
}
.contentTransition(.symbolEffect(.replace))
}
.foregroundColor(.white)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.glassEffect(
.regular,
in: RoundedRectangle(cornerRadius: 20)
)
.glassEffectID("playerCard", in: playerNamespace)
.onTapGesture {
withAnimation(.spring(duration: 0.5, bounce: 0.15)) {
showDetails = true
}
}
.padding(.horizontal, 16)
.padding(.bottom, 16)
}
}
}
}
}
}
Di contoh ini, kita pakai beberapa teknik sekaligus:
glassEffect()dengan berbagai style dan shapeGlassEffectContaineruntuk mengelompokkan elemen glassglassEffectID()untuk animasi morphing antara mini player dan expanded playertint()untuk sentuhan warna pada tombol play/pauseinteractive()untuk feedback visual saat ditekancontentTransition(.symbolEffect(.replace))untuk transisi SF Symbol yang mulus- Spring animation untuk transisi yang terasa natural
Kalau kamu mau eksperimen, coba ganti spring duration dan bounce value-nya. Setiap kombinasi menghasilkan feel yang berbeda — dan menemukan yang "pas" itu bagian serunya.
Aksesibilitas: Jangan Sampai Terlupakan
Satu hal yang saya apresiasi dari implementasi Liquid Glass di SwiftUI adalah dukungan aksesibilitas yang sudah built-in. Tapi tetap ada beberapa hal yang perlu kamu perhatikan.
Reduce Transparency
Saat pengguna mengaktifkan Reduce Transparency di pengaturan aksesibilitas, glassEffect() secara otomatis fallback ke tampilan yang lebih opaque. Kamu nggak perlu menulis kode tambahan untuk ini — sistem yang menangani semuanya.
Increase Contrast
Hal yang sama berlaku saat Increase Contrast diaktifkan. Sistem otomatis menyesuaikan opacity dan blur glass untuk memenuhi persyaratan kontras. Lagi-lagi, ini terjadi otomatis tanpa intervensi dari kamu.
Best Practice Aksesibilitas
// Kamu bisa cek environment variable jika perlu logika kustom
@Environment(\.accessibilityReduceTransparency)
var reduceTransparency
// Tapi umumnya, biarkan sistem yang menangani
Text("Label Informasi")
.padding()
.glassEffect(reduceTransparency ? .identity : .regular)
Umumnya, cara terbaik adalah membiarkan sistem menangani aksesibilitas secara otomatis. Hanya gunakan pengecekan manual kalau kamu punya kebutuhan yang sangat spesifik yang nggak bisa ditangani perilaku default.
Dan satu reminder — hindari menempatkan informasi kritis hanya pada warna tint glass. Warna tersebut mungkin nggak terlihat di semua mode aksesibilitas, jadi selalu sediakan indikator visual tambahan (seperti icon atau label teks).
Best Practices dan Tips Produksi
Setelah banyak bereksperimen (dan melihat pengalaman developer lain yang sudah adopsi Liquid Glass di aplikasi produksi), berikut beberapa tips yang menurut saya paling penting:
1. Jangan Taruh Glass di Semua Tempat
Ini kesalahan paling umum, dan jujur saya juga sempat tergoda melakukannya. Terlalu banyak lapisan glass akan menumpuk masalah kontras dan bikin UI jadi "kabur". Bayangkan tab bar + card + sheet yang semuanya glass — hasilnya tumpukan blur yang nggak terbaca. Solusinya sederhana: spacing dan restraint. Kurangi, bukan tambahkan.
2. Hapus Background Sebelum Menambahkan Glass
Modifier .background() yang sudah ada akan memblokir efek glass. Pastikan kamu hapus background solid sebelum menambahkan .glassEffect(). Ini hal simpel tapi sering bikin bingung saat debugging.
3. Gunakan GlassEffectContainer untuk Grup
Selalu bungkus elemen-elemen glass yang terkait dalam GlassEffectContainer. Ini bukan cuma soal estetika — container juga membantu sistem mengoptimalkan rendering. Win-win.
4. Performa? Tenang Saja
Dalam pengujian real-world, dampak Liquid Glass terhadap baterai kurang dari 1%. GPU load ditangani secara efisien oleh Apple Silicon modern. Jadi selama implementasimu benar, performa bukan sesuatu yang perlu kamu khawatirkan.
5. Migrasi Aplikasi Existing Itu Mudah
Kabar baiknya, aplikasi yang sudah menggunakan komponen standar SwiftUI atau UIKit akan otomatis mendapatkan tampilan Liquid Glass tanpa perubahan kode — cukup kompilasi ulang dengan SDK iOS 26. Komponen sistem seperti navigation bar, tab bar, dan toolbar sudah otomatis di-update. Jadi untuk banyak kasus, kamu nggak perlu ngapa-ngapain.
6. Chaining Modifier
Kamu bisa gabungkan style, tint, dan interactive dalam satu chain yang rapi:
// Semua modifier bisa di-chain
.glassEffect(.regular.tint(.blue).interactive())
// Atau dengan lebih detail
.glassEffect(
.clear
.tint(.purple.opacity(0.6))
.interactive(),
in: RoundedRectangle(cornerRadius: 16)
)
FAQ: Pertanyaan yang Sering Diajukan
Apakah Liquid Glass bisa digunakan di iOS versi lama?
Sayangnya tidak. API Liquid Glass seperti glassEffect(), GlassEffectContainer, dan glassEffectID() hanya tersedia mulai iOS 26. Kalau aplikasimu perlu mendukung versi sebelumnya, gunakan #available(iOS 26, *) check untuk memberikan fallback. Sisi positifnya, komponen standar SwiftUI otomatis mendapatkan tampilan Liquid Glass saat dikompilasi dengan SDK iOS 26 — jadi setidaknya bagian itu gratis.
Apakah Liquid Glass mempengaruhi performa dan baterai?
Dampaknya sangat minimal. Dalam pengujian, perbedaan konsumsi baterai kurang dari 1%. GPU load ditangani dengan baik oleh Apple Silicon. Selama kamu nggak overuse dan pakai GlassEffectContainer untuk grup, performa bukan masalah.
Apa perbedaan antara .regular, .clear, dan .identity?
.regular adalah gaya default dengan blur dan refraksi standar — cocok untuk kebanyakan elemen navigasi. .clear memberikan transparansi lebih tinggi sehingga konten di belakang lebih terlihat. Dan .identity menonaktifkan efek glass sepenuhnya sambil mempertahankan layout — berguna untuk toggle kondisional tanpa menyebabkan layout shift.
Bagaimana cara membuat animasi morphing antar elemen glass?
Tiga bahan utamanya: GlassEffectContainer, @Namespace, dan glassEffectID(). Berikan ID yang sama ke dua view dalam state yang berbeda, bungkus perubahan state dengan withAnimation(), dan SwiftUI akan otomatis handle transisi morphing-nya. Simpel tapi hasilnya luar biasa.
Apakah Liquid Glass mendukung aksesibilitas?
Ya, dan ini salah satu aspek yang paling rapi dari implementasinya. Reduce Transparency membuat glass otomatis fallback ke tampilan solid. Increase Contrast menyesuaikan opacity dan blur secara otomatis. Kamu nggak perlu kode tambahan. Satu-satunya hal yang perlu diingat: jangan taruh informasi penting hanya pada warna tint glass, karena warna itu mungkin nggak terlihat di semua mode aksesibilitas.