Liquid Glass w SwiftUI: trzy wzorce z wdrożenia Return na iOS 26
Liquid Glass od Apple to jednolinijkowe API w SwiftUI: .glassEffect().1 Return, mój minutnik medytacyjny, używa go dziewięć razy w wersjach na iOS, macOS i tvOS.2 Jedno z tych zastosowań aplikuje modyfikator do niestandardowego Shape, który zamienia same cyfry minutnika w płynne szkło, glif po glifie.

Interesujące pytanie brzmi: co dzieje się, gdy wykracza się poza tę jedną linijkę. Human Interface Guidelines od Apple ustanawiają ścisłą zasadę warstwowania: Liquid Glass należy do warstwy funkcjonalnej (kontrolki, nawigacja, ulotne UI), a nigdy do warstwy treści.3 Większość z dziewięciu zastosowań w Return to podręcznikowe aplikacje warstwy funkcjonalnej: pickery, przyciski, paski kontrolek, plakietki stanu pauzy. Interesujące są te trzy, które naginają reguły, nie łamiąc ich.
Niniejszy esej omawia trzy wzorce, które wdrożyłem, reguły, których przestrzegają, pułapki, w jakie wpadłem, oraz powierzchnię API, której świadomie nie wykorzystałem.
TL;DR
- iOS 26 udostępnia Liquid Glass jako
.glassEffect(_:in:). Domyślny wariant to.regular, a domyślny kształt toCapsule.1 - Return wykorzystuje trzy wzorce wykraczające poza jednolinijkowiec: szkło na niestandardowym
Shape(tekst minutnika poprzez ścieżki glifów Core Text), wzorzec lustra (odbicie poniżej za pomocą odwróconej i zamaskowanej kopii) oraz nakładki HUD warstwy funkcjonalnej. - Reguła HIG od Apple: Liquid Glass dla warstwy funkcjonalnej, standardowe materiały dla warstwy treści.3
- Świadomie nie zastosowałem
GlassEffectContainer. API przekształceń kształtów nie ma zastosowania w Return (żaden element szklany nie animuje się w inny), a luki wydajnościowej renderowania nie zmierzyłem; jest to nieoceniony kompromis, nie rekomendacja.1 - Pułapki: szkło na płaskim tle czyta się jako płaskie; renderowanie cyfr bez drgań wymaga komórek o stałej szerokości;
HStackw tvOS ignoruje wartość środowiskową kierunku układu; redukcja ruchu musi być respektowana w animacji morfingu.
Jednolinijkowe API i reguła warstwowania
Apple udostępnia Liquid Glass z niewielką powierzchnią, wprowadzoną jako główny filar projektowy podczas 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
Trzy pokrętła: wariant (.regular lub .clear), kształt (dowolny Shape) oraz łańcuch GlassEffectStyle (zabarwienie, interaktywność). To całe API dla pojedynczego widoku. Renderowanie wielu widoków obsługuje oddzielny GlassEffectContainer, do którego jeszcze powrócę.
HIG jest ściślejszy niż API. Human Interface Guidelines od Apple definiują dwie warstwy w każdym interfejsie iOS 26+:3
- Warstwa treści: dokument, lista, zdjęcie lub multimedia, które konsumuje użytkownik. Tutaj należy używać standardowych materiałów (istniejących
.regularMaterial,.thinMaterialitp.). - Warstwa funkcjonalna: kontrolki, nawigacja, paski kart, paski boczne, ulotne nakładki. Tutaj należy używać Liquid Glass.
Konkretne wskazanie Apple: „Nie używaj Liquid Glass w warstwie treści. Liquid Glass działa najlepiej, gdy zapewnia wyraźne rozróżnienie między elementami interaktywnymi a treścią, a włączenie go do warstwy treści może skutkować niepotrzebną złożonością i myląca hierarchią wizualną.”3
Reguła brzmi restrykcyjnie, dopóki nie odniesie się jej do prawdziwej aplikacji. Return jest minutnikiem medytacyjnym. Jego warstwą treści są obrazy oddechu i zapętlone wideo, które płynie za wszystkim. Jego warstwą funkcjonalną są wybór czasu trwania, stos przycisków start/pauza/stop, drugorzędny rząd przycisków ustawień oraz (na tvOS) plakietka stanu pauzy. Osiem z dziewięciu zastosowań szkła w Return to podręcznikowe aplikacje warstwy funkcjonalnej: trzy warianty wyboru czasu trwania dla ścieżek kodu iOS i macOS, przełącznik start/pauza, przycisk stop, rząd przycisków ustawień, wskaźnik pauzy w tvOS oraz jeszcze jedna ulotna nakładka kontrolek.4
Dziewiąty to świadomy przypadek graniczny (Liquid Glass na samych cyfrach minutnika), który omawia kolejna sekcja.
Wzorzec 1: Szkło na niestandardowym Shape
Cyfry minutnika w Return nie są tekstem narysowanym nad szklanym tłem. Szkło jest tekstem. .glassEffect(.clear, in:) przyjmuje dowolny Shape,9 a Shape to protokół tworzący Path.10 Zatem sztuczka polega na: przekonwertowaniu ciągu znaków minutnika na ścieżkę glifów za pomocą Core Text,11 a następnie przekazaniu tej ścieżki jako Shape do .glassEffect.56
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))
}
}
Rzeczywisty kod produkcyjny z Return/Return/GlassTextShape.swift.5 Funkcja path(in:) używa Core Text do rozłożenia ciągu, przechodzi przez każde CTRun, wyodrębnia CGPath każdego glifu i łączy je w jedno CGMutablePath. Dwa nieoczywiste kroki następują po połączeniu: układ współrzędnych Core Text umieszcza początek w lewym dolnym rogu, podczas gdy Path w SwiftUI umieszcza go w lewym górnym rogu, więc ścieżka musi zostać odwrócona przez CGAffineTransform(scaleX: 1, y: -1). Następnie boundingRect odwróconej ścieżki ma ujemne wartości y, więc translacja ponownie wyśrodkowuje ją wewnątrz prostokąta, który SwiftUI przekazuje do Shape. Pominięcie którejkolwiek transformacji powoduje, że glify renderują się do góry nogami lub poza ekranem.
Następnie aplikacja to pojedyncza linia:
Rectangle()
.fill(.clear)
.glassEffect(.clear, in: textShape)
.frame(width: cellWidth, height: cellHeight)
Przezroczysty Rectangle jest zastępczym celem dotyku; faktyczny wizualny efekt to ten kształt, który tworzy textShape. Ze ścieżką glifu jako kształtem, materiał Liquid Glass wypełnia tylko kontury glifów. Rezultat: każda cyfra minutnika jest osobną formą z płynnego szkła, załamującą cokolwiek animuje się za nią.6
Niuans HIG. Deklarowana reguła Apple to Liquid Glass dla warstwy funkcjonalnej, standardowe materiały dla warstwy treści, z jednym wyraźnym wyjątkiem: ulotne interaktywne kontrolki w warstwie treści (suwaki, przełączniki) mogą przyjąć Liquid Glass po aktywacji.3 Cyfry minutnika w Return są wyświetlaczem stanu, a nie kontrolką: aktualizują się raz na sekundę z Timer.publish(every: 1, ...) i nie mają gestu dotykowego (przycisk start/pauza pod nimi przełącza stan). Zatem umieszczenie na nich Liquid Glass jest świadomym przypadkiem granicznym, bliższym „ulotnej interaktywnej kontrolce” pod względem zamiaru niż dosłownej interaktywności, ponieważ cyfry są wizualnym punktem skupienia, na który użytkownicy patrzą przez całą sesję. Naginam regułę, nie łamię jej. Recenzent czytający HIG ściśle mógłby argumentować, że powinien być to standardowy materiał; ja argumentuję, że minutnik jest powierzchnią kontrolną upływającego czasu z tej samej rodziny co wskaźnik postępu. Dokumentacja Apple nie rozstrzyga tej sprawy bezpośrednio.
Dlaczego niestandardowy Shape zamiast Text + tło. Text renderowany nad szklanym tłem czyta się jako tekst na szkle. Text renderowany jako samo szkło czyta się jako inna kategoria wizualna. Użytkownik postrzega cyfry jako funkcjonalny pierwszy plan, konkretnie jako element ulotny, który istnieje, by patrzeć przez niego, a nie na niego.
Wzorzec 2: Wzorzec lustra
Return pokazuje odbicie minutnika pod nim, zanikające. Rzeczywisty kod produkcyjny:6

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)
}
}
Trzy transformacje komponują lustro, wszystkie standardowe prymitywy SwiftUI:14
scaleEffect(x: 1, y: -1)odwraca drugą kopię do góry nogami..mask(LinearGradient(...))zanika odbicie od 20% nieprzezroczystości u góry do całkowitej przezroczystości na 60% w dół..offset(y: -8)podciąga odbicie o 8 punktów w górę, aby przylegało do oryginału, zamiast pozostawiać widoczną szczelinę.
Modyfikator .accessibilityHidden(true) na odbiciu jest kluczowy. VoiceOver nie powinien dwukrotnie ogłaszać czasu lustrzanego; oryginalny accessibilityLabel i accessibilityAddTraits(.updatesFrequently) są już dołączone do głównej instancji GlassTimerText powyżej, a odbicie ma charakter czysto dekoracyjny.
Dlaczego działa to konkretnie z Liquid Glass. Odbicie dziedziczy materiał szklany z GlassTimerText. Każde tło, na którym znajduje się oryginał (gradient oddychającego okręgu, wideo, tonowana scena), załamuje się przez obie kopie. Lustro nie potrzebuje żadnego kodu specyficznego dla szkła; materiał szklany obsługuje załamanie za darmo. Cały efekt to trzy modyfikatory i gradient.
Koszt dostępności. Użytkownicy z redukcją ruchu nadal widzą lustro, ale animacja materiału szklanego między aktualizacjami czasu jest tłumiona w innym miejscu przez @Environment(\.accessibilityReduceMotion).7 Samo odbicie jest statyczne; animuje się tylko morfing między przejściami cyfr.
Wzorzec 3: Szklane nakładki HUD dla ulotnych kontrolek
Pozostałe osiem zastosowań szkła w Return to podręcznikowe aplikacje warstwy funkcjonalnej.4 Każde podąża za tym samym wzorcem:

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))) to kluczowa część. Liquid Glass na ulotnych kontrolkach wydaje się odpowiedni tylko wtedy, gdy kontrolki przechodzą. Statyczny szklany HUD, który stale tkwi na ekranie, czyta się jako chrom. Szklany HUD, który zanika i skaluje się w momencie dotknięcia przez użytkownika i z powrotem, gdy odwraca wzrok, czyta się jako chwilowa powierzchnia kontrolna.
Dokumentacja Apple dla glassEffect wskazuje to pośrednio: modyfikator „przechwytuje treść do wysłania do kontenera w celu renderowania” oraz „reaguje na interakcje dotykowe i wskaźnikowe w czasie rzeczywistym.”1 Haki animacji nie znajdują się w API, ale potok renderowania zakłada, że elementy szklane się poruszają. Statyczne elementy szklane omijają tę afordancję.
Return wykorzystuje ten wzorzec dla wyboru czasu trwania (wsuwa się od dołu, gdy użytkownik dotyka), przycisku przełącznika start/pauza (zawsze widoczny, ale skaluje się przy naciśnięciu), przycisku stop (widoczny tylko w trakcie sesji), rzędu przycisków ustawień (poziomy pasek kontrolek pod wyborem czasu trwania) oraz plakietki stanu pauzy w tvOS (widoczna tylko, gdy sesja jest wstrzymana na Apple TV). Wszystkie pięć kontekstów respektuje regułę warstwy funkcjonalnej HIG.3

Kwestia GlassEffectContainer
Apple zaleca GlassEffectContainer zawsze, gdy aplikacja używa .glassEffect() na wielu widokach, z dwóch powodów: lepszej wydajności renderowania (efekty szklane są wsadowe) oraz możliwości przekształcania kształtów w siebie nawzajem podczas przejść.1
Nie zastosowałem go. Rozumowanie jest specyficzne dla aplikacji, a nie obaleniem wytycznych Apple. Return ma dziewięć widoków szklanych, z których żaden nie musi przekształcać się między sobą.46 Wybór czasu trwania nigdy nie animuje się w przycisk startu. Tekst minutnika nigdy nie animuje się w rząd przycisków ustawień. Każdy element szklany jest niezależny. API przekształceń nie miałoby zastosowania, na które mogłoby zareagować, a reguły odstępów kontenera ograniczałyby układy, które dziś nie wymagają koordynacji.
Argumentu wydajnościowego renderowania nie mogę w pełni odeprzeć bez pomiaru. Dokumentacja Apple ostrzega, że „zbyt wiele” efektów szklanych poza kontenerem może pogorszyć wydajność.1 Dziewięć widoków Return nigdy nie współdzieli ekranu jednocześnie (wybór czasu trwania pojawia się tylko w stanie menu, przycisk stop tylko podczas pauzy w trakcie sesji). W dowolnej klatce liczę trzy lub cztery widoczne elementy szklane, co działało płynnie na każdym urządzeniu, które testowałem na iOS, iPadOS, macOS, watchOS i tvOS, ale nie przeprowadziłem śladu instruments porównującego wersję opakowaną w kontener z wersją z samymi modyfikatorami. Zatem szczere przedstawienie sprawy: Return pomija GlassEffectContainer na podstawie zaobserwowanego dobrego doświadczenia użytkownika, a nie zmierzonej równoważności wydajnościowej.
Reguła, którą z tego wyprowadziłem: GlassEffectContainer jest dla aplikacji, w których wiele elementów szklanych jest widocznych i animowanych jednocześnie. Przykład Apple to renderowanie zestawu symboli z glassEffectUnion(id:namespace:): cztery symbole pogody, które płynnie łączą się i rozdzielają jako jedna jednostka.1 To podręcznikowy przypadek użycia. Jeśli przyszła funkcja Return będzie wymagała, by elementy szklane przekształcały się lub współdzieliły reguły odstępów kontenera, kontener jest właściwym narzędziem, które należy wówczas dodać. Dla dzisiejszej aplikacji jeszcze nie natrafiłem na taki przypadek.
Pułapki, w jakie wpadłem
Trzy rzeczywiste błędy z produkcji:
Drgania szklanych cyfr. SF Pro Rounded ma cyfry o zmiennej szerokości w renderowaniu proporcjonalnym. Gdy minutnik odliczał, długość wyświetlanego ciągu się zmieniała, a otaczający HStack przepływał co sekundę, powodując drgania całego minutnika. Naprawa: komórki o stałej szerokości dla każdego znaku. Każda cyfra otrzymuje cellWidth równy fontSize * 0.6, każdy dwukropek otrzymuje fontSize * 0.3, a HStack staje się stabilną siatką.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)
}
}
Komórki nie są standardem Apple; są obejściem dla renderowania o zmiennej szerokości przy małych stałych rozmiarach czcionki. SF Pro Rounded od Apple z .monospacedDigit() rozwiązałoby ten sam problem na Text, ale modyfikator nie jest dostępny dla niestandardowego renderera szklanego opartego na Shape. Układ stałych komórek to substytut.
Nadpisanie kierunku układu w tvOS. Ten sam GlassTimerText działał na iOS, iPadOS, macOS i tvOS. Konkretnie na tvOS HStack lustrzano odbijał się w środowisku języka pisanego od prawej do lewej, mimo że wersja iOS respektowała nadpisanie środowiskowe. Naprawa: przypiąć kierunek układu zarówno przez wartość środowiskową, jak i przez jawny modyfikator flipsForRightToLeftLayoutDirection(false), zastosowany bezpośrednio do HStack komórek cyfr (nadrzędny VStack osobno stosuje nadpisanie środowiska, aby kopia odbicia je dziedziczyła):6
HStack(spacing: 0) { ... }
.flipsForRightToLeftLayoutDirection(false)
.environment(\.layoutDirection, .leftToRight)
Powód: HStack w tvOS wydaje się ignorować nadpisanie na poziomie środowiska w niektórych wersjach, a flipsForRightToLeftLayoutDirection(false) to jawny kontrakt braku odbicia, który jest bardziej niezawodnie respektowany.12 Pas i szelki.
Redukcja ruchu w morfingu cyfr. Liquid Glass domyślnie animuje przejścia morfingu między wyświetlanymi ciągami. Użytkownicy z włączonym accessibilityReduceMotion widzieli morfing jako migotanie. Naprawa:6
.animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: displayTime)
Modyfikator animacji odczytuje @Environment(\.accessibilityReduceMotion) i całkowicie wyłącza przejście, gdy redukcja ruchu jest aktywna. Wytyczne dostępności Apple są jednoznaczne: każda dekoracyjna animacja musi respektować preferencje ruchu użytkownika.7
Kiedy nie używać Liquid Glass
Odmowa to część projektowania.
Nie umieszczaj Liquid Glass w warstwie treści. HIG od Apple jest jednoznaczny, a ignorowanie reguły powoduje mylącą hierarchię: użytkownik nie potrafi rozpoznać, co jest interaktywne, a co jest treścią.3 Jeśli efekt szklany dekoruje wiersz listy lub kartę zdjęcia, projekt walczy z platformą.
Nie używaj szkła nad płaskim tłem. Liquid Glass załamuje to, co jest za nim. Jeśli „to, co jest za nim” jest pojedynczym jednolitym kolorem, załamanie nie ma czego załamywać, a rezultat czyta się jako płaski tonowany prostokąt. Albo umieść szkło nad zróżnicowaną treścią (gradient, obraz, wideo), albo nie używaj szkła w ogóle. Ekran minutnika w Return wyświetla obrazy okładkowe oparte na motywie i zapętlone wideo jako tło przez VideoBackgroundView,4 specjalnie po to, by elementy szklane nad nim zawsze miały teksturę do załamywania.
Bądź ostrożny ze szkłem na treści o wysokiej częstotliwości. Renderowanie materiału szklanego jest związane z GPU, a domyślna animacja morfingu między zmianami kształtu szkła sama jest animacją. Minutnik aktualizujący się raz na sekundę jest w porządku w moim testowaniu; przebieg fali lub wizualizator audio przy 60 Hz jest niesprawdzony i prawdopodobnie walczy z animacją morfingu. Nie zmierzyłem górnej granicy; traktuj to jako heurystykę, nie zmierzony próg. Dokumentacja Apple żadnego nie publikuje.
Nie wdrażaj szkła bez przetestowania redukcji ruchu. Każda animacja szklana powinna być zabezpieczona przez accessibilityReduceMotion.7 Domyślny morfing między kształtami szklanymi to efekt kinetyczny, a nie tylko wygaszanie.
Co Liquid Glass oznacza dla aplikacji wdrażanych na iOS 26+
Teza jest prosta. Liquid Glass jest jednolinijkowym API tylko wtedy, gdy aplikacja już respektuje regułę warstwowania HIG. Aplikacja SwiftUI, która umieszcza kontrolki w warstwie funkcjonalnej, a treść w warstwie treści, może przyjąć Liquid Glass z modyfikatorami .glassEffect() i domyślnie sprawiać wrażenie natywnej.
Aplikacje, które mieszają obie warstwy (kontrolki wewnątrz wierszy listy, paski nawigacji traktowane jako treść, dekoracyjny chrom na kartach zdjęć), przyjmą Liquid Glass i będą sprawiały wrażenie niewłaściwych. Materiał jest poprawny; architektura pod nim nie.
Wzorzec niestandardowego Shape (Wzorzec 1) rozszerza tę regułę w czysty sposób. Wszystko, co funkcjonalnie jest kontrolką, może przyjąć Liquid Glass, nawet jeśli nie wygląda na „kontrolkę” w konwencjonalnym sensie. Minutnik jest kontrolką, miernik poziomu jest kontrolką, wskaźnik postępu jest kontrolką. Liquid Glass na każdym z nich jest zgodny ze specyfikacją.
Połącz ten wpis z moimi wcześniejszymi opracowaniami na temat wdrażania warstwy danych tej samej aplikacji przez App Intents oraz przez serwer MCP (MCP server). Warstwa wizualna jest trzecią powierzchnią tego samego stosu: typowane encje dla systemowej AI, format pliku dla agentów między LLM a Liquid Glass dla człowieka przy urządzeniu.8
FAQ
Czy mogę używać .glassEffect() na platformach innych niż iOS 26?
Modyfikator .glassEffect() to iOS 26+, iPadOS 26+, macOS 26+, watchOS 26+, tvOS 26+, visionOS 26+. Platformy sprzed wersji 26 mają .background(.regularMaterial) i podobne, które wytwarzają efekty matowego szkła, ale nie nowe załamanie Liquid Glass.1
Czy GlassEffectContainer zmienia wygląd?
Elementy szklane opakowane w kontener mogą łączyć swoje kształty, gdy ich reguły odstępów powodują nakładanie się. Bez kontenera każdy .glassEffect() jest niezależny. Dla aplikacji, w których elementy szklane powinny płynnie łączyć się podczas animacji, GlassEffectContainer jest właściwym narzędziem. Dla aplikacji, w których każdy element szklany pozostaje wyraźny, kontener jest narzutem.1
Dlaczego nie używać Text bezpośrednio z .foregroundStyle(.thinMaterial)?
thinMaterial to standardowy materiał, a nie Liquid Glass. Wizualnie jest to nakładka matowego szkła, a nie efekt załamującego światło szkła Liquid Glass.3 Dla tekstu, który ma wyglądać konkretnie jak nowy materiał, .glassEffect(.clear, in: customShape) jest wspieraną ścieżką.
Jak wykonać zrzut ekranu Liquid Glass do celów marketingowych?
Efekty szklane są renderowane przez GPU w czasie wykonania, więc zrzuty ekranu są wykonywane z symulatora lub urządzenia z już zastosowanym efektem. Oficjalne obrazy referencyjne Liquid Glass od Apple pochodzą ze stron dokumentacji HIG i sesji WWDC 2025.3
Czy GlassTextShape działa dla dowolnego tekstu, czy tylko dla cyfr?
Działa każdy ciąg, który Core Text może rozłożyć. Return wykorzystuje go dla cyfr i dwukropka, ale ten sam Shape działa dla liter, symboli, emoji (z odpowiednią czcionką) lub mieszanych ciągów. Wydajność jest ograniczona liczbą glifów; długi akapit renderowany jako szkło byłby kosztowny, ale sześcioznakowy minutnik jest trywialny.
Trzy wzorce, jedna reguła i jedno API, które świadomie pominąłem. Liquid Glass jest trzecią powierzchnią aplikacji iOS 26+, siedzącą na wierzchu typowanych encji i współdzielonych formatów plików. Jednolinijkowe API jest prawdziwe. Reguła HIG pod nim jest tym, co sprawia, że jednolinijkowiec działa.
Bibliografia
-
Apple Developer, „Applying Liquid Glass to custom views”. Dokumentacja modyfikatora
glassEffect(_:in:),GlassEffectContainer,glassEffectUnion(id:namespace:),glassEffectID(_:in:)orazGlassEffectTransition. Wariant domyślny.regular, kształt domyślnyCapsule. ↩↩↩↩↩↩↩↩↩↩ -
Autorska aplikacja Return, minutnik medytacyjny opublikowany w App Store 21 kwietnia 2026 roku, dostępny na iPhone, iPad, Mac, Apple Watch i Apple TV. Wykorzystuje SwiftUI, SwiftData oraz HealthKit na iOS 26+ / macOS 26+. ↩
-
Apple Developer, Human Interface Guidelines „Materials”. Definiuje regułę warstwy funkcjonalnej kontra warstwa treści dla Liquid Glass: „Don’t use Liquid Glass in the content layer.” Wymienia warianty regular i clear oraz ich zamierzone zastosowania. ↩↩↩↩↩↩↩↩↩
-
Kod produkcyjny w
Return/Return/ContentView.swift(siedem miejsc wywołań.glassEffect()),Return/Return/GlassTimerText.swift(jedno miejsce wywołania naGlassDigitCell) orazReturn/ReturnTV/TVContentView.swift(jedno miejsce wywołania na wskaźniku „Paused” w tvOS). Łącznie dziewięć. PlusReturn/Return/VideoBackgroundView.swift, który renderuje obrazy okładkowe oparte na motywie i zapętlone wideo, przez które elementy szklane się załamują. ↩↩↩↩ -
Kod produkcyjny w
Return/Return/GlassTextShape.swift. Opakowanie zgodne zShapewokół Core Text. Utworzone 26 listopada 2025 roku, zawarte w wersji 1.0 wdrożonej w App Store. ↩↩ -
Kod produkcyjny w
Return/Return/GlassTimerText.swift. WidokiGlassDigitCell,GlassTimerTextorazGlassTimerDisplay. Implementuje układ komórek o stałej szerokości, odbicie lustrzane oraz zabezpieczenie redukcji ruchu. ↩↩↩↩↩↩↩ -
Apple Developer, wartość środowiska „accessibilityReduceMotion”. Aplikacje muszą respektować preferencje ruchu użytkownika; domyślne animacje morfingu na Liquid Glass powinny być zabezpieczone tą wartością. ↩↩↩
-
Analiza autora w App Intents Are Apple’s New API to Your App oraz Two Agent Ecosystems, One Shopping List. Model trzech powierzchni: App Intents dla Apple Intelligence, MCP dla agentów między LLM, Liquid Glass dla człowieka przy urządzeniu. ↩
-
Apple Developer, „glassEffect(_:in:isEnabled:)” na
View. Parametrin:przyjmuje dowolny typ zgodny zShape. Domyślny kształt toCapsule. ↩ -
Apple Developer, protokół „Shape”.
Shapeto dowolny typ, który tworzyPathdla danego prostokąta. Niestandardowe kształty mogą opakowywać dowolne daneCGPath. ↩ -
Apple Developer, „Core Text Programming Guide” oraz
CTLineCreateWithAttributedString. Core Text to silnik tekstowy niższego poziomu używany do rozkładania ciągów atrybutowych na uruchomienia glifów i wyodrębniania ścieżek na glif. ↩ -
Apple Developer, „flipsForRightToLeftLayoutDirection(_:)”. Jawnie nadpisuje lustrzane odbicie RTL na
Viewniezależnie od otaczającej wartości środowiska\.layoutDirection. ↩ -
Apple, „WWDC 2025 Highlights” via Apple Newsroom. Liquid Glass ogłoszony jako jednoczący materiał projektowy w iOS 26, iPadOS 26, macOS 26, watchOS 26, tvOS 26 i visionOS 26. Sesje: „Meet Liquid Glass” (WWDC 2025), „Build a SwiftUI app with Liquid Glass”. ↩
-
Apple Developer, „LinearGradient”, „scaleEffect(x:y:anchor:)”, „mask(_:)”. Standardowe prymitywy SwiftUI, wszystkie dostępne od iOS 13. ↩