Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

As you have seen in previous lessons, Apple has made a giant effort to make Liquid Glass simple to adopt for developers. This effort means the majority of apps gain the benefits of Liquid Glass with little changes.

There are certain situations however, where not even Apple making changes to the System Frameworks will help. To address this, Apple have provided new APIs for developers to use and make their apps feel natural using Liquid Glass.

The Glass Effect Modifier

The first advanced technique relates to applying Liquid Glass effects to custom views. If you’ve spent a significant amount of time building a custom UI in your app, you may need to make some additional changes to get that Liquid Glass effect.

The Create Card Screen is shown
Hve Kxuuna Cikx Hhjoob ip mqinx

ToolbarItem(placement: .bottomBar) {

}
var body: some View {
  NavigationStack {
    VStack {
      GeometryReader { proxy in
        CardDetailView(
          card: $card,
          viewScale: Settings.calculateScale(proxy.size))
        frame(
          width: Settings.calculateSize(proxy.size).width,
          height: Settings.calculateSize(proxy.size).height)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .modifier(CardToolbar(
          currentModal: $currentModal,
          card: $card))
      }
      Spacer()
      HStack {
        Image(systemName: "eraser.fill")
          .frame(width: 40.0, height: 40.0)
          .glassEffect(.regular.tint(.blue).interactive())
        Image(systemName: "textformat.size")
          .frame(width: 40.0, height: 40.0)
          .glassEffect()
        Text("More")
          .padding(8.0)
          .glassEffect(in: .rect(cornerRadius: 16.0))
      }
      .onDisappear {
        card.save()
      }
      .onChange(of: scenePhase) { _, newScenePhase in
        if newScenePhase == .inactive {
          card.save()
        }
      }
    }
  }
}
The liquid glass modifier applied to different components
Vha tetual mgekn taweneat asstaen ru ligbepupl zaqpalurnt

Glass Effect Containers and Morphing Effects

As you learned in the previous section, SwiftUI controls can apply Liquid Glass in highly configurable ways. This configurability means the material is applying effects such as refraction to each control. Combine that with the layering and sense of depth Liquid Glass gives, and you’re beginning to need some computationally intensive effects.

ToolbarItemGroup(placement: .bottomBar) {
  GlassEffectContainer(spacing: 60.0) {
    HStack(spacing: 40.0) {
      Image(systemName: "scribble.variable")
        .frame(width: 40.0, height: 40.0)
        .glassEffect()
        .glassEffectID("pencil", in: namespace)
      if isExpanded {
        Image(systemName: "eraser.fill")
          .frame(width: 40.0, height: 40.0)
          .glassEffect()
          .glassEffectID("eraser", in: namespace)
        Image(systemName: "textformat.size")
          .frame(width: 40.0, height: 40.0)
          .glassEffect()
          .glassEffectID("text", in: namespace)
      }
    }
  }
}
ToolbarItemGroup(placement: .bottomBar) {
  Button {
    withAnimation {
      isExpanded.toggle()
    }
  } label: {
    Label("More", systemImage: "arrow.up.left.and.arrow.down.right")
  }
  .buttonStyle(.glass)
}
// ... other properties ...
 @State private var isExpanded: Bool = false
 @Namespace private var namespace
The Bottom toolbar using a Glass Effect Container
Lwi Huyjab raivquh ovexr e Xjoyc Ixpunv Luqbeomaw

The Bottom toolbar is animated in using the Glass Effect Container
Mtu Maphag peoxkup ew atamofux os ubaqc qte Chifw Iwxewg Bulzaetox

Cleaning up the UI

To finish, it’s time to clean up after yourself. The UI at the bottom of the Cards app is starting to look busy. Open SingleCardView.swift and remove the HStack added earlier:

NavigationStack {
  VStack {
    // Keep the other controls in VStack
    HStack {
      Image(systemName: "eraser.fill")
        .frame(width: 40.0, height: 40.0)
        .glassEffect(.regular.tint(.blue).interactive())
      Image(systemName: "textformat.size")
        .frame(width: 40.0, height: 40.0)
        .glassEffect()
      Text("More")
        .padding(8.0)
        .glassEffect(in: .rect(cornerRadius: 16.0))
    }
  }
}
if(selectedCard == nil) {
  ToolbarSpacer(.flexible, placement: .bottomBar)
  ToolbarItemGroup(placement: .bottomBar) {
    createButton
    settingsButton
  }
}
The Bottom toolbar is looking alot cleaner and easier to understand
Bca Benkof leayqot iz boazuvx ozew zjoiquf ojy uowoex hi eqdiscwewq

See forum comments
Download course materials from Github
Previous: Introduction Next: Conclusion