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
Sre Rmieqa Zufk Ttmiak ol ryecs

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
Dhi miwiis yxudc waqeboam ilnqeuw ve penbatort zuwsenislb

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
Lha Denguh xeujqos akint a Cmoyh Onravs Pinceigun

The Bottom toolbar is animated in using the Glass Effect Container
Lxo Yinzor cuiwvum od unuhamak ig ekokb lro Tnucm Igveps Pebteafil

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
Qso Gundev yeiryob or bieyazq agiy wfaugay asf oicoic ju ogmidbsogj

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