15.3 C
Canberra
Tuesday, October 21, 2025

The best way to create a liquid glass toolbar button that adapt to background content material


I’ve the next code making an attempt to create a two rows toolbar as I’ve seen from iOS Safari 26, however the issue is the ToolbarButton struct does not actually adapt to the background coloration, it stayed darkish when on darkish background.

I attempted to make use of .glassEffect however it creates a small bubble relying on the form of the image, which does not look good with different buttons on the toolbar. I additionally tried to make use of .buttonStyle(.glass) which additionally creates a capsule bubble round every button as nicely.

I additionally tried to group all of the buttons with the glass container in a namespace, that is shut however it simply teams all my buttons, once I wished to share the only glass panel with the search area.

All I actually wished was only for the Picture foreground coloration to be adaptive to the background scrollview’s content material.

// MARK: - Principal concern: Toolbar Button, however not adaptive to background content material coloration
HStack(spacing: 20) {
    Picture(systemName: "home.fill")
        .font(.system(dimension:36))
        .body(width: 40, peak: 40)
    Picture(systemName: "textual content.magnifyingglass")
        .font(.system(dimension:36))
        .body(width: 40, peak: 40)
    Picture(systemName: "plus.circle.fill")
        .font(.system(dimension:36))
        .body(width: 40, peak: 40)
}
import SwiftUI

@predominant
struct GlassToolbarDemoApp: App {
    var physique: some Scene {
        WindowGroup {
            DemoView()
        }
    }
}

struct DemoView: View {
    @State personal var question: String = ""
    @Namespace personal var namespace

    var physique: some View {
        ZStack {
            SampleBackgroundScroll()
                .ignoresSafeArea() // let content material run beneath the glass for a greater impact
        }
        // Pin our two-row glass toolbar to the TOP. Change to .backside to make it a backside toolbar.
        .safeAreaInset(edge: .backside) {
            VStack(spacing: 8) {
                GlassEffectContainer{
                    HStack(spacing: 10) {
                        // Search area
                        HStack(spacing: 8) {
                            Picture(systemName: "magnifyingglass")
                                .foregroundStyle(.secondary)
                            TextField("Search…", textual content: $question)
                                .textInputAutocapitalization(.by no means)
                        }
                        .padding(.horizontal, 12)
                        .padding(.vertical, 10)
                        .background(
                            RoundedRectangle(cornerRadius: 14, model: .steady)
                                .fill(.thinMaterial)
                        )
                    }
                    .body(maxWidth: .infinity, alignment: .main)
                    .padding(.horizontal, 2)
                        .glassEffect()
                        .glassEffectUnion(id: "toolbar", namespace: namespace)
                    Divider().opacity(0.25)
                    
                    // MAIN PROBLEM: How will we make the foreground coloration of those pictures adaptive
                    // like a buttonStyle(.glass) however with out the bubble round them.
                    HStack(spacing: 20) {
                        Picture(systemName: "home.fill")
                            .font(.system(dimension:36))
                            .body(width: 40, peak: 40)
                        Picture(systemName: "textual content.magnifyingglass")
                            .font(.system(dimension:36))
                            .body(width: 40, peak: 40)
                        Picture(systemName: "plus.circle.fill")
                            .font(.system(dimension:36))
                            .body(width: 40, peak: 40)
                    }
                }
                
            }
            .padding(.horizontal, 14)
            .padding(.vertical, 10)
            .body(maxWidth: .infinity)
            .glassEffect(.clear)
            .padding(.horizontal)
            .padding(.high, 6)
            .shadow(coloration: .black.opacity(0.12), radius: 20, y: 10)
        }
    }
}

// MARK: - Demo background content material to point out mild/darkish behind glass
struct SampleBackgroundScroll: View {
    var physique: some View {
        ScrollView {
            LazyVStack(spacing: 0) {
                demoBlock(.mild, title: "Sunny Paper")
                demoBlock(.darkish, title: "Night time Slate")
                demoBlock(.mild, title: "Porcelain")
                demoBlock(.colourful, title: "Aurora Cyan")
                demoBlock(.darkish, title: "Graphite")
                demoBlock(.colorfulAlt, title: "Sundown Mix")
                demoBlock(.mild, title: "Foggy White")
                demoBlock(.darkish, title: "Charcoal")
            }
        }
    }

    @ViewBuilder
    func demoBlock(_ model: BlockStyle, title: String) -> some View {
        ZStack {
            swap model {
            case .mild:
                LinearGradient(colours: [Color.white, Color(white: 0.93)], startPoint: .topLeading, endPoint: .bottomTrailing)
            case .darkish:
                LinearGradient(colours: [Color.black, Color(white: 0.15)], startPoint: .high, endPoint: .backside)
            case .colourful:
                LinearGradient(colours: [Color.cyan.opacity(0.7), Color.blue.opacity(0.4)], startPoint: .topLeading, endPoint: .bottomTrailing)
            case .colorfulAlt:
                LinearGradient(colours: [Color.purple, Color.orange], startPoint: .topLeading, endPoint: .bottomTrailing)
            }

            VStack(spacing: 12) {
                Textual content(title)
                    .font(.system(dimension: 28, weight: .daring))
                    .foregroundStyle(model == .darkish ? .white : .main)
                Textual content("Scroll to see how the glass adapts to totally different backgrounds.")
                    .font(.system(dimension: 15))
                    .foregroundStyle(model == .darkish ? .white.opacity(0.85) : .secondary)
            }
            .padding(.high, 120)
        }
        .body(peak: 360)
    }

    enum BlockStyle { case mild, darkish, colourful, colorfulAlt }
}


#Preview {
    DemoView()
}



The best way to create a liquid glass toolbar button that adapt to background content material

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles