← 所有文章

SwiftUI 中的 Liquid Glass:在 iOS 26 上推出 Return 學到的三種模式

Apple 的 Liquid Glass 是一行 SwiftUI API:.glassEffect()1 我的冥想計時器 Return 在 iOS、macOS 與 tvOS 上總共使用了它九次。2 其中一次將此修飾符套用到自訂的 Shape,把計時器數字本身逐一字形地變成 liquid glass。

iPhone 上的 Return — 計時器數字本身透過自訂 Shape 渲染為 Liquid Glass(下方模式 1 會詳述);時長選擇器是一個 Liquid Glass HUD

有趣的問題在於,當你超越這一行程式碼時會發生什麼。Apple 的人機介面指南(Human Interface Guidelines)訂下了一條嚴格的分層規則:Liquid Glass 屬於功能層(控制項、導覽、暫態 UI),絕不屬於內容層。3 Return 的九次使用中,大多數都是教科書般的功能層應用:選擇器、按鈕、控制列、暫停狀態徽章。真正有趣的是其中三個在不打破規則的前提下彎曲了規則的用法。

本文逐一介紹我所推出的三種模式、它們所遵守的規則、讓我栽過跟頭的陷阱,以及我刻意不使用的 API 介面。

Apple 的人機介面指南透過三種材質變體來定義 Liquid Glass。regular 變體會根據其底下的內容調整外觀(左例為深色,右例為淺色);clear 變體則以遠少的過濾讓底層細節透出來:3

深色背景上的 Liquid Glass regular 變體 — Apple HIG 參考圖

淺色背景上的 Liquid Glass regular 變體 — Apple HIG 參考圖

Liquid Glass clear 變體 — Apple HIG 參考圖,展示 clear 變體如何讓底層內容的視覺細節透出來

參考圖出自 Apple 的 Materials HIG 頁面3 這兩種變體都是 .glassEffect() 在 SwiftUI 中所產生的結果;兩者之間的選擇只是該修飾符上的一個引數。

TL;DR

  • iOS 26 將 Liquid Glass 以 .glassEffect(_:in:) 的形式推出。預設變體為 .regular,預設形狀為 Capsule1
  • Return 使用了三種超越這一行程式碼的模式:將玻璃套用於自訂 Shape(透過 Core Text 字形路徑呈現的計時器文字)、鏡面模式(以翻轉並遮罩的副本在下方呈現反射),以及功能層的 HUD 疊加層。
  • Apple 的 HIG 規則:Liquid Glass 用於功能層,標準材質用於內容層。3
  • 我刻意不使用 GlassEffectContainer。其變形(morphing)API 在 Return 中沒有使用情境(沒有任何玻璃元素會動畫變形成另一個),而我也尚未測試其渲染效能的差距;這是一項未經量測的取捨,並非建議。1
  • 陷阱:平面背景上的玻璃看起來會很平;要讓數字渲染無抖動需要固定寬度的儲存格;tvOS 的 HStack 會忽略版面方向的環境值;變形動畫上必須尊重減少動態(reduce-motion)的設定。

關於相鄰的 Apple UI 模式,請閱讀 SwiftUI layout protocol 深入解析SF Pro 字體排印系統,以及 Symbol Effects 詞彙表

一行 API 與分層規則

Apple 推出的 Liquid Glass 介面範圍很小,在 WWDC 2025 上作為主要設計支柱之一登場:113

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()                              // default: .regular variant, Capsule shape

Text("Hello, World!")
    .glassEffect(in: .rect(cornerRadius: 16))   // custom shape

Text("Hello, World!")
    .glassEffect(.regular.tint(.orange).interactive())  // tint + touch reactivity

三個調節項:變體(.regular.clear)、形狀(任何 Shape),以及 GlassEffectStyle 鏈(色調、互動性)。這就是單一檢視的全部 API。多檢視渲染則由另一個 GlassEffectContainer 處理,稍後會談到它。

HIG 比 API 更為嚴謹。Apple 的人機介面指南在每個 iOS 26+ 介面中定義了兩個層:3

  1. 內容層: 使用者正在消費的文件、清單、相片或媒體。在此使用標準材質(既有的 .regularMaterial.thinMaterial 等)。
  2. 功能層: 控制項、導覽、標籤列、側邊欄、暫態疊加層。在此使用 Liquid Glass

Apple 的具體指示是:「不要在內容層使用 Liquid Glass。Liquid Glass 在於互動元素與內容之間提供清楚區隔時效果最佳,將它納入內容層可能造成不必要的複雜度與令人混淆的視覺階層。」3

這條規則聽起來很有限制性,直到你把它對應到一個真實的 App 上。Return 是一個冥想計時器。它的內容層是呼吸意象與在一切之後循環播放的影片。它的功能層是時長選擇器、開始/暫停/停止按鈕堆疊、次要的設定按鈕列,以及(在 tvOS 上)暫停狀態徽章。Return 的九次玻璃使用中有八次是教科書般的功能層應用:三種給 iOS 與 macOS 程式碼路徑用的時長選擇器變體、開始/暫停切換、停止按鈕、設定按鈕列、tvOS 暫停指示器,以及另一個暫態控制疊加層。4

第九次是刻意設計的邊界案例(將 Liquid Glass 套用於計時器數字本身),下一節會逐步說明。

模式 1:將玻璃套用於自訂 Shape

Return 中的計時器數字並不是繪製在玻璃背景之上的文字。玻璃就是那些文字。.glassEffect(.clear, in:) 接受任何 Shape9Shape 是一個產生 Path 的協定。10 所以訣竅是:使用 Core Text 把計時器字串轉換成字形路徑,11 然後將這個 path-as-Shape 傳給 .glassEffect56

import SwiftUI
@preconcurrency import CoreText

struct GlassTextShape: Shape {
    let text: String
    let font: CTFont

    func path(in rect: CGRect) -> Path {
        guard !text.isEmpty else { return Path() }
        let combinedPath = CGMutablePath()

        let attrString = NSAttributedString(string: text, attributes: [.font: font])
        let line = CTLineCreateWithAttributedString(attrString)
        guard let runs = CTLineGetGlyphRuns(line) as? [CTRun], !runs.isEmpty else {
            return Path()
        }

        for run in runs {
            let glyphCount = CTRunGetGlyphCount(run)
            guard glyphCount > 0 else { continue }
            var glyphs = [CGGlyph](repeating: 0, count: glyphCount)
            var positions = [CGPoint](repeating: .zero, count: glyphCount)
            let range = CFRange(location: 0, length: glyphCount)
            CTRunGetGlyphs(run, range, &glyphs)
            CTRunGetPositions(run, range, &positions)

            for i in 0..<glyphCount {
                guard let glyphPath = CTFontCreatePathForGlyph(font, glyphs[i], nil) else { continue }
                let transform = CGAffineTransform(translationX: positions[i].x, y: positions[i].y)
                combinedPath.addPath(glyphPath, transform: transform)
            }
        }

        // Core Text y-axis is flipped vs SwiftUI; flip then re-bound and center.
        var swiftPath = Path(combinedPath).applying(CGAffineTransform(scaleX: 1, y: -1))
        let flippedBounds = swiftPath.boundingRect
        let offsetX = rect.midX - flippedBounds.midX
        let offsetY = rect.midY - flippedBounds.midY
        return swiftPath.applying(CGAffineTransform(translationX: offsetX, y: offsetY))
    }
}

取自 Return/Return/GlassTextShape.swift 的真實正式環境程式碼。5 path(in:) 函式使用 Core Text 排版字串、走訪每個 CTRun、擷取每個字形的 CGPath,並將它們聯集成一個 CGMutablePath。兩個不那麼顯而易見的步驟發生在聯集之後:Core Text 的座標系統將原點置於左下角,而 SwiftUI 的 Path 則置於左上角,因此這條路徑必須透過 CGAffineTransform(scaleX: 1, y: -1) 翻轉。接著翻轉後路徑的 boundingRect 會有負的 y 值,所以需要一次位移把它重新置中於 SwiftUI 交給 Shape 的那個 rect 之內。少了任何一個變換,字形就會上下顛倒或跑到畫面外。

接著套用只是一行:

Rectangle()
    .fill(.clear)
    .glassEffect(.clear, in: textShape)
    .frame(width: cellWidth, height: cellHeight)

那個 clear 的 Rectangle 是一個命中目標的佔位符;實際的視覺則是 textShape 所產生的任何形狀。有了字形路徑的形狀,Liquid Glass 材質就只會填滿字形的輪廓。結果是:計時器的每個數字都是一個獨立的 liquid-glass 形體,折射出在它後面運行的任何動畫。6

HIG 的細微之處。 Apple 訂下的規則是Liquid Glass 用於功能層,標準材質用於內容層,並有一個明確的例外:內容層中的暫態互動控制項(滑桿、切換開關)在啟用時可以採用 Liquid Glass。3 Return 中的計時器數字是狀態顯示,而非控制項:它們每秒從 Timer.publish(every: 1, ...) 更新一次,且沒有點按手勢(在它們底下的開始/暫停按鈕才是切換狀態的元件)。因此把 Liquid Glass 套用到它們身上是一個刻意設計的邊界案例,從意圖上而言比從字面互動性而言更接近「暫態互動控制項」,因為這些數字是使用者整段時間都在注視的視覺焦點。我是在彎曲規則,而非打破它。嚴格按照 HIG 解讀的審查者可能會主張這應該用標準材質;我則主張這個計時器是一個時間流逝的控制表面,與進度指示器屬於同一類。Apple 的文件並未直接裁決這個案例。

為何選擇自訂 Shape 而非 Text + 背景。 渲染在玻璃背景之上的 Text 讀起來像是玻璃上的文字。渲染成玻璃本身Text 則讀起來像是另一種視覺類別。使用者會把那些數字感知為功能性前景,具體來說是一個存在著供人透視、而非注視的暫態元素。

模式 2:鏡面模式

Return 在計時器下方顯示一個逐漸淡出的反射。真實的正式環境程式碼:6

Mac 上的 Return — 作為 Liquid Glass HUD 疊加層的時長選擇器,上方可見計時器文字的玻璃處理

VStack(spacing: 0) {
    GlassTimerText(text: displayTime, fontSize: fontSize)
        .accessibilityLabel("Time remaining: \(accessibleDescription)")

    if showReflection {
        GlassTimerText(text: displayTime, fontSize: fontSize)
            .scaleEffect(x: 1, y: -1)
            .mask(
                LinearGradient(
                    stops: [
                        .init(color: .white.opacity(0.2), location: 0),
                        .init(color: .clear, location: 0.6)
                    ],
                    startPoint: .top,
                    endPoint: .bottom
                )
            )
            .offset(y: -8)
            .accessibilityHidden(true)
    }
}

三個變換組成了這面鏡子,全都是標準的 SwiftUI 基本元件:14

  1. scaleEffect(x: 1, y: -1) 將第二份副本上下翻轉。
  2. .mask(LinearGradient(...)) 讓反射從頂部 20% 不透明度淡出到向下 60% 處完全透明。
  3. .offset(y: -8) 把反射往上拉 8 點,使它緊貼原件,而不留下可見的接縫。

反射上的 .accessibilityHidden(true) 修飾符是關鍵所在。VoiceOver 不應該把鏡像的時間念兩次;原件的 accessibilityLabelaccessibilityAddTraits(.updatesFrequently) 已經附加在上方主要的 GlassTimerText 實例上,而反射純屬裝飾。

為何這特別適用於 Liquid Glass。 反射繼承了來自 GlassTimerText 的玻璃材質。原件所坐落的任何背景(呼吸圓的漸層、一段影片、一個帶色調的場景)都會折射穿過這兩份副本。鏡子不需要任何玻璃專屬的程式碼;玻璃材質免費處理了折射。整個效果只是三個修飾符加上一個漸層。

無障礙的代價。 啟用減少動態的使用者仍會看到鏡子,但玻璃材質在時間更新之間的動畫則在他處透過 @Environment(\.accessibilityReduceMotion) 被抑制了。7 反射本身是靜態的;只有數字過渡之間的變形才會產生動畫。

模式 3:用於暫態控制項的玻璃 HUD 疊加層

Return 中其餘的八次玻璃使用都是教科書般的功能層應用。4 每一個都遵循相同的模式:

Apple Watch 上的 Return — 在小畫布尺寸下的功能層 Liquid Glass

durationPicker
    .frame(height: 50)
    .frame(maxWidth: 320)
    .glassEffect()
    .padding(.horizontal, 20)
    .transition(.opacity.combined(with: .scale(scale: 0.95)))

.transition(.opacity.combined(with: .scale(scale: 0.95))) 是關鍵所在。暫態控制項上的 Liquid Glass 只有在控制項過渡時才感覺對味。一個永久坐在螢幕上的靜態玻璃 HUD 讀起來像是裝飾框架(chrome)。一個在使用者點按時淡入並縮放、在他們移開視線時又淡出的玻璃 HUD,讀起來則像是一個瞬間的控制表面。

Apple 關於 glassEffect 的文件隱含地指出了這一點:此修飾符「擷取要傳送給容器以進行渲染的內容」並「即時對觸控與指標互動作出反應」。1 動畫的掛鉤並不在 API 之中,但渲染管線假設玻璃元素會移動。靜態的玻璃元素會錯失那種可供性(affordance)。

Return 將此模式用於時長選擇器(使用者點按時向上滑出)、開始/暫停切換按鈕(始終可見但按下時會縮放)、停止按鈕(僅在工作階段進行中可見)、設定按鈕列(位於時長選擇器下方的一條水平控制列),以及 tvOS 暫停狀態徽章(僅在 Apple TV 上工作階段暫停時可見)。這五個情境全都尊重 HIG 的功能層規則。3

Apple 的 tvOS 參考圖:Liquid Glass 疊加層漂浮在影片背景之上,讓底層媒體透出來 — 典型的 10 呎 UI 使用情境

Apple HIG 參考圖:tvOS 中的 Liquid Glass 疊加層位於媒體層之上,讓它透出來。3 Return 的 tvOS 實作遵循同樣的模型:控制項漂浮在循環播放的火焰/森林/流水背景之上。

來自實驗室的工具列備註。 WWDC 2026 的一場 SwiftUI Group Lab 座談更精確地說明了這在 toolbar 中如何呈現。在 toolbar 中放置非玻璃內容(範例是一張個人資料照片)需要 sharedBackgroundVisibility(.hidden),讓該項目捨棄其共用的玻璃背景並直接顯示照片。15 該座談標示了一項細部調整:一個較新的 API 只移除 toolbar 按鈕的內容邊距,而以往隱藏背景是唯一的手段,且它會把背景與邊距一併移除。至於 toolbar 按鈕本身,該座談則導向使用 prominent 按鈕樣式(glassProminent)與 buttonBorderShape,而非直接在按鈕上動用 .glassEffect。其底層的 HIG 立場正是本文所環繞的同一條分層規則:Liquid Glass 屬於裝飾框架,而非內容區域,因為一個底下沒有內容捲動的玻璃表面,並沒有東西可供折射。153

GlassEffectContainer 的問題

Apple 建議,只要 App 在多個檢視上使用 .glassEffect(),就應使用 GlassEffectContainer,原因有二:更佳的渲染效能(玻璃效果會被批次處理),以及在過渡期間將形狀彼此變形的能力。1

我沒有使用它。這個理由是針對特定 App 的,並非對 Apple 指引的反駁。Return 有九個玻璃檢視,沒有一個需要彼此變形。46 時長選擇器從不會動畫變形成開始按鈕。計時器文字從不會動畫變形成設定按鈕列。每個玻璃元素都是獨立的。變形 API 沒有任何使用情境可供觸發,而容器的間距規則則會限制那些今天並不需要協調的版面。

渲染效能的論點我則無法在沒有量測的情況下完全反駁。Apple 的文件警告,容器之外「太多」的玻璃效果可能會降低效能。1 Return 的九個檢視從不會同時共處一個螢幕(時長選擇器只在選單狀態出現,停止按鈕只在工作階段進行中暫停時出現)。在任一給定的影格上,我數到三或四個可見的玻璃元素,而這在我跨 iOS、iPadOS、macOS、watchOS 與 tvOS 測試過的每一台裝置上都很流暢,但我並未執行 instruments 追蹤來比較容器包裹與僅用修飾符的差異。因此誠實的說法是:Return 跳過 GlassEffectContainer 是基於觀察到良好的使用者體驗,而非經過量測的效能等同性。

我從中得出的規則是:GlassEffectContainer 適用於多個玻璃元素同時可見並產生動畫的 App。 Apple 的範例是使用 glassEffectUnion(id:namespace:) 的符號集渲染:四個天氣符號流暢地合併與分裂,宛如一個單元。1 那是教科書般的使用情境。如果 Return 未來的某個功能需要玻璃元素變形或共用容器的間距規則,那時容器就是要加上的正確工具。對於今天的 App 而言,我還沒碰上這個案例。

讓我栽過跟頭的陷阱

三個來自正式環境的真實 bug:

玻璃數字抖動。 SF Pro Rounded 在比例渲染中具有可變寬度的數字。隨著計時器倒數,顯示的字串長度會改變,於是周圍的 HStack 每秒重新排版,讓整個計時器抖動。修法:為每個字元使用固定寬度的儲存格。每個數字取得 fontSize * 0.6cellWidth,每個冒號取得 fontSize * 0.3,於是 HStack 變成一個穩定的網格。6

HStack(spacing: 0) {
    ForEach(Array(text.enumerated()), id: \.offset) { _, char in
        let isColon = char == ":"
        let cellWidth = isColon ? colonCellWidth : digitCellWidth
        GlassDigitCell(character: String(char), font: ctFont,
                       cellWidth: cellWidth, cellHeight: cellHeight)
    }
}

這些儲存格並非 Apple 標準;它們是針對小型固定字級下比例寬度渲染的權宜之計。Apple 的 SF Pro Rounded 搭配 .monospacedDigit()Text 上能解決同樣的問題,但這個修飾符無法用於自訂的 Shape 為基礎的玻璃渲染器。固定儲存格的版面就是它的替代方案。

tvOS 版面方向覆寫。 同一個 GlassTimerText 在 iOS、iPadOS、macOS 與 tvOS 上運行。專門在 tvOS 上,即使 iOS 版本尊重環境內的覆寫,HStack 卻在從右至左(Right-to-Left)的語言環境下被鏡像了。修法:同時透過環境值與明確的 flipsForRightToLeftLayoutDirection(false) 修飾符固定版面方向,直接套用於數字儲存格的 HStack(父層的 VStack 另外套用環境覆寫,好讓反射副本繼承它):6

HStack(spacing: 0) { ... }
    .flipsForRightToLeftLayoutDirection(false)
    .environment(\.layoutDirection, .leftToRight)

原因:tvOS 的 HStack 在某些版本中似乎會忽略環境層級的覆寫,而 flipsForRightToLeftLayoutDirection(false) 是更可靠被尊重的明確「不鏡像」契約。12 雙重保險。

數字變形上的減少動態。 Liquid Glass 預設會為所顯示字串之間的變形過渡加上動畫。啟用 accessibilityReduceMotion 的使用者會看到變形呈現為閃爍。修法:6

.animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: displayTime)

這個 animation 修飾符讀取 @Environment(\.accessibilityReduceMotion),並在減少動態開啟時完全停用該過渡。Apple 的無障礙指引很明確:任何裝飾性動畫都必須尊重使用者的動態偏好設定。7

何時不該使用 Liquid Glass

拒絕也是設計的一部分。

不要把 Liquid Glass 放進內容層。 Apple 的 HIG 很明確,忽視這條規則會產生混亂的階層:使用者無法分辨什麼是可互動的、什麼是內容。3 如果一個玻璃效果正在裝飾一個清單列或一張相片卡,那麼這個設計就是在和平台對著幹。

不要在平面背景上使用玻璃。 Liquid Glass 折射它背後的東西。如果「它背後的東西」是單一純色,折射就沒有東西可彎曲,結果讀起來會像是一個帶色調的平面矩形。要嘛把玻璃放在多變的內容(漸層、影像、影片)之上,要嘛根本不要用玻璃。Return 的計時器螢幕透過 VideoBackgroundView 將以主題為基礎的封面意象與循環影片作為背景運行,4 正是為了讓其上方的玻璃元素始終有可供折射的紋理。

對於高頻內容上的玻璃要謹慎。 玻璃材質渲染受 GPU 限制,而玻璃形狀變化之間的預設變形動畫本身就是一個動畫。在我的測試中,每秒更新一次的計時器沒問題;以 60 Hz 運行的波形或音訊視覺化工具則未經驗證,且很可能會與變形動畫相衝突。我並未測試其上限;請把它當作經驗法則,而非量測過的門檻。Apple 的文件也未公布任何門檻。

未測試減少動態前不要推出玻璃。 每個玻璃動畫都應以 accessibilityReduceMotion 為條件。7 玻璃形狀之間的預設變形是一種動態效果,而不只是淡入淡出。

Liquid Glass 對於在 iOS 26+ 上推出的 App 意味著什麼

這個論點很小。唯有當 App 已經尊重 HIG 的分層規則時,Liquid Glass 才是一行 API。 一個把控制項放在功能層、把內容放在內容層的 SwiftUI App,可以用 .glassEffect() 修飾符採用 Liquid Glass,並且預設就感覺原生。

混淆兩層的 App(控制項放在清單列裡、導覽列被當成內容對待、相片卡上有裝飾性的裝飾框架)採用 Liquid Glass 後會感覺不對。材質是正確的;它底下的架構不對。

自訂 Shape 的模式(模式 1)乾淨地延伸了這條規則。任何在功能上是控制項的東西都可以採用 Liquid Glass,即使它看起來不像傳統意義上的「控制項」。計時器是一個控制項,電平表是一個控制項,進度指示器是一個控制項。在這些東西上使用 Liquid Glass 都符合規範。

請將本文與我先前關於透過 App Intents 以及透過 MCP server 推出同一個 App 資料層的文章一併閱讀。視覺層是同一個技術堆疊的第三個表面:給系統 AI 的型別化實體、給跨 LLM 代理的檔案格式,以及給裝置前那個人的 Liquid Glass。8

FAQ

我可以在非 iOS 26 平台上使用 .glassEffect() 嗎?

.glassEffect() 修飾符需要 iOS 26+、iPadOS 26+、macOS 26+、watchOS 26+、tvOS 26+、visionOS 26+。26 之前的平台有 .background(.regularMaterial) 之類的選項,能產生霧面玻璃效果,但不是新的 Liquid Glass 折射。1

GlassEffectContainer 會改變視覺嗎?

被容器包裹的玻璃元素在其間距規則造成重疊時可以把形狀混合在一起。沒有容器的話,每個 .glassEffect() 都是獨立的。對於玻璃元素應在動畫期間流暢合併的 App,GlassEffectContainer 是正確的工具。對於每個玻璃元素都保持獨立的 App,容器則是額外開銷。1

為何不直接用 Text 搭配 .foregroundStyle(.thinMaterial)

thinMaterial 是一種標準材質,不是 Liquid Glass。其視覺是一個霧面玻璃疊加層,而非 Liquid Glass 那種折射並彎曲光線的玻璃效果。3 對於應該專門看起來像新材質的文字,.glassEffect(.clear, in: customShape) 是受支援的途徑。

我該如何擷取 Liquid Glass 截圖用於行銷?

玻璃效果是在執行階段由 GPU 渲染的,所以截圖是在效果已經套用的情況下從模擬器或裝置擷取。Apple 官方的 Liquid Glass 參考意象來自他們的 HIG 文件頁面與 WWDC 2025 議程。3

GlassTextShape 適用於任意文字還是只適用於數字?

任何 Core Text 能排版的字串都行得通。Return 把它用於數字與一個冒號,但同一個 Shape 也適用於字母、符號、emoji(搭配正確的字型)或混合字串。其效能受字形數量所限;以玻璃渲染的長段落會很昂貴,但一個六字元的計時器則微不足道。


三種模式、一條規則,以及一個我刻意跳過的 API。Liquid Glass 是 iOS 26+ App 的第三個表面,坐落在型別化實體與共用檔案格式之上。這一行 API 是真的。讓這一行得以成立的,是它底下的那條 HIG 規則。

References


  1. Apple Developer, “Applying Liquid Glass to custom views”. Documentation for the glassEffect(_:in:) modifier, GlassEffectContainer, glassEffectUnion(id:namespace:), glassEffectID(_:in:), and GlassEffectTransition. Default variant .regular, default shape Capsule

  2. Author’s Return, a meditation-timer app published on the App Store on April 21, 2026, available for iPhone, iPad, Mac, Apple Watch, and Apple TV. Uses SwiftUI, SwiftData, and HealthKit on iOS 26+ / macOS 26+. 

  3. Apple Developer, “Materials” Human Interface Guidelines. Defines the functional vs content layer rule for Liquid Glass: “Don’t use Liquid Glass in the content layer.” Lists the regular and clear variants and their intended uses. 

  4. Production code in Return/Return/ContentView.swift (seven .glassEffect() call sites), Return/Return/GlassTimerText.swift (one call site on GlassDigitCell), and Return/ReturnTV/TVContentView.swift (one call site on the tvOS “Paused” indicator). Total nine. Plus Return/Return/VideoBackgroundView.swift, which renders the theme-based cover imagery and looped video that the glass elements refract through. 

  5. Production code in Return/Return/GlassTextShape.swift. The Shape-conforming wrapper around Core Text. Created November 26, 2025, included in shipped App Store v1.0. 

  6. Production code in Return/Return/GlassTimerText.swift. GlassDigitCell, GlassTimerText, and GlassTimerDisplay views. Implements fixed-width cell layout, the mirror reflection, and reduce-motion gating. 

  7. Apple Developer, “accessibilityReduceMotion” environment value. Apps must honor the user’s motion preference; default morph animations on Liquid Glass should be gated on the value. 

  8. Author’s analysis in App Intents Are Apple’s New API to Your App and Two Agent Ecosystems, One Shopping List. The three-surface model: App Intents for Apple Intelligence, MCP for cross-LLM agents, Liquid Glass for the human at the device. 

  9. Apple Developer, “glassEffect(_:in:isEnabled:)” on View. The in: parameter accepts any Shape-conforming type. The default shape is Capsule

  10. Apple Developer, “Shape” protocol. A Shape is any type that produces a Path for a given rectangle. Custom shapes can wrap arbitrary CGPath data. 

  11. Apple Developer, “Core Text Programming Guide” and CTLineCreateWithAttributedString. Core Text is the lower-level text engine used to lay out attributed strings into glyph runs and extract per-glyph paths. 

  12. Apple Developer, “flipsForRightToLeftLayoutDirection(_:)”. Explicitly overrides RTL mirroring on a View regardless of the surrounding \.layoutDirection environment value. 

  13. Apple, “WWDC 2025 Highlights” via Apple Newsroom. Liquid Glass announced as the unifying design material across iOS 26, iPadOS 26, macOS 26, watchOS 26, tvOS 26, and visionOS 26. Sessions: “Meet Liquid Glass” (WWDC 2025), “Build a SwiftUI app with Liquid Glass”

  14. Apple Developer, “LinearGradient”, “scaleEffect(x:y:anchor:)”, “mask(_:)”. Standard SwiftUI primitives, all available since iOS 13. 

  15. Apple, WWDC 2026 SwiftUI Group Lab (session 2). Paraphrased from a locally transcribed recording of the WWDC 2026 SwiftUI Group Lab (session 2); Apple publishes no official captions for the labs. Source for hiding a toolbar item’s shared glass background to show non-glass content (a profile photo), the newer API that removes only a toolbar button’s content margin rather than the background and margin together, the preference for the prominent glass button style and buttonBorderShape over .glassEffect on a button, and the chrome-not-content layering rationale. The supporting symbols are documented at sharedBackgroundVisibility(_:) on CustomizableToolbarContent, which takes a Visibility value such as .hidden, and buttonBorderShape(_:); glassProminent is the prominent Liquid Glass PrimitiveButtonStyle. The specific content-margin API named in the lab could not be confirmed against Apple’s published documentation, so it is described by behavior rather than asserted by symbol. 

相關文章

iOS 26 上的 HealthKit + SwiftUI:授權、樣本類型,以及兩款上架 App 的跨平台模式

來自 Water(飲水追蹤、HKQuantitySample)與 Return(正念冥想、HKCategorySample)的真實生產級模式。權限體驗、async 包裝、watchOS 變體,以及務必避開的陷阱。

5 分鐘閱讀

@Observable 內部機制:巨集、註冊器,以及 ObservableObject 的根本錯誤

@Observable 以逐屬性存取追蹤取代 ObservableObject 的廣播模型。本文剖析巨集展開、註冊器運作機制,以及遷移過程中的陷阱。

3 分鐘閱讀

品味即是基礎建設

當代理程式生成的內容愈來愈多地進入產品,品質天花板取決於您將審美判斷編碼進系統的能力。品味在可查詢時才能規模化。

1 分鐘閱讀