@mmerterden/multi-agent-pipeline 20.17.1 → 20.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/docs/facts.json +6 -6
- package/install/catalog-history.json +1 -1
- package/manifest.json +75 -37
- package/package.json +1 -1
- package/pipeline/skills/.skill-manifest.json +33 -13
- package/pipeline/skills/.skills-index.json +66 -11
- package/pipeline/skills/shared/README.md +18 -13
- package/pipeline/skills/shared/external/NOTICE-avdlee-swiftui-agent-skill.md +3 -1
- package/pipeline/skills/shared/external/NOTICE-dimillian-skills.md +2 -1
- package/pipeline/skills/shared/external/hig-app-icons/SKILL.md +159 -0
- package/pipeline/skills/shared/external/hig-app-icons/evals/evals.json +48 -0
- package/pipeline/skills/shared/external/hig-app-icons/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/hig-app-icons/references/icon-workflow.md +115 -0
- package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +32 -4
- package/pipeline/skills/shared/external/hig-components-layout/evals/evals.json +47 -0
- package/pipeline/skills/shared/external/hig-components-layout/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/hig-components-layout/references/bars-and-tabs.md +231 -0
- package/pipeline/skills/shared/external/hig-components-layout/references/containers.md +5 -30
- package/pipeline/skills/shared/external/hig-components-status/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-foundations/SKILL.md +23 -4
- package/pipeline/skills/shared/external/hig-foundations/evals/evals.json +47 -0
- package/pipeline/skills/shared/external/hig-foundations/evals/trigger-eval.json +21 -0
- package/pipeline/skills/shared/external/hig-foundations/references/foundations-detail.md +34 -26
- package/pipeline/skills/shared/external/hig-foundations/references/type-color-spacing.md +219 -0
- package/pipeline/skills/shared/external/hig-inputs/SKILL.md +5 -4
- package/pipeline/skills/shared/external/hig-patterns/SKILL.md +19 -3
- package/pipeline/skills/shared/external/hig-patterns/references/onboarding-and-states.md +188 -0
- package/pipeline/skills/shared/external/hig-patterns/references/patterns.md +5 -11
- package/pipeline/skills/shared/external/hig-platforms/SKILL.md +17 -5
- package/pipeline/skills/shared/external/hig-platforms/references/ipad-layout.md +218 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +4 -1
- package/pipeline/skills/shared/external/ios-accessibility/references/large-content-and-appearance.md +135 -0
- package/pipeline/skills/shared/external/ios-design-review/SKILL.md +146 -0
- package/pipeline/skills/shared/external/ios-design-review/evals/evals.json +48 -0
- package/pipeline/skills/shared/external/ios-design-review/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/ios-design-review/references/appearance-matrix.md +135 -0
- package/pipeline/skills/shared/external/ios-design-review/references/checklist.md +193 -0
- package/pipeline/skills/shared/external/ios-haptics/SKILL.md +191 -0
- package/pipeline/skills/shared/external/ios-haptics/evals/evals.json +49 -0
- package/pipeline/skills/shared/external/ios-haptics/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/ios-haptics/references/core-haptics.md +215 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/NOTICE.md +53 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/SKILL.md +170 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/evals/evals.json +50 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/references/api-map.md +212 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/references/fixed-assumptions.md +145 -0
- package/pipeline/skills/shared/external/ios-iphone-duo/references/poses-and-panes.md +122 -0
- package/pipeline/skills/shared/external/ios-sf-symbols/SKILL.md +177 -0
- package/pipeline/skills/shared/external/ios-sf-symbols/evals/evals.json +49 -0
- package/pipeline/skills/shared/external/ios-sf-symbols/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/ios-sf-symbols/references/effects-and-custom-symbols.md +135 -0
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +38 -50
- package/pipeline/skills/shared/external/swiftui-animation/evals/evals.json +47 -0
- package/pipeline/skills/shared/external/swiftui-animation/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +7 -73
- package/pipeline/skills/shared/external/swiftui-animation/references/scroll-effects.md +185 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +6 -6
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-advanced.md +3 -253
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-basics.md +4 -47
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-transitions.md +3 -111
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/liquid-glass.md +11 -381
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +184 -224
- package/pipeline/skills/shared/external/swiftui-liquid-glass/evals/evals.json +47 -0
- package/pipeline/skills/shared/external/swiftui-liquid-glass/evals/trigger-eval.json +22 -0
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +246 -33
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/uikit-glass.md +227 -0
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +15 -18
- package/pipeline/skills/shared/external/swiftui-ui-patterns/references/components-index.md +1 -1
- package/pipeline/skills/shared/external/swiftui-ui-patterns/references/haptics.md +6 -68
- package/pipeline/skills/skills-index.md +16 -11
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +0 -786
|
@@ -1,287 +1,247 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: swiftui-liquid-glass
|
|
3
|
-
description: "Liquid Glass in SwiftUI
|
|
3
|
+
description: "Liquid Glass in SwiftUI and UIKit: navigation-layer use, regular versus clear, glassEffect, GlassEffectContainer, morphing, glass buttons, ConcentricRectangle, the compatibility opt-out and material fallbacks. Use when implementing, reviewing or adopting Liquid Glass, or choosing glass versus a material."
|
|
4
4
|
metadata:
|
|
5
5
|
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Liquid Glass
|
|
9
9
|
|
|
10
|
-
Apple's 26 releases (iOS and iPadOS, macOS, tvOS, watchOS) introduced a
|
|
11
|
-
material called Liquid Glass. It blurs what lies behind it, picks up color and
|
|
12
|
-
from its surroundings, and
|
|
10
|
+
Apple's 26 releases (iOS and iPadOS, macOS, tvOS, watchOS) introduced a
|
|
11
|
+
material called Liquid Glass. It blurs what lies behind it, picks up color and
|
|
12
|
+
light from its surroundings, and reacts to touch and pointer input.
|
|
13
13
|
|
|
14
|
-
System chrome gets it for free:
|
|
15
|
-
|
|
16
|
-
views and controls.
|
|
17
|
-
|
|
14
|
+
System chrome gets it for free: an app built with the 26 SDK shows glass tab
|
|
15
|
+
bars, toolbars, navigation bars, sheets and popovers without code changes. The
|
|
16
|
+
APIs here are for custom views and controls. This skill is the one place
|
|
17
|
+
Liquid Glass is described; other skills point here.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
### 1. Implement a new feature
|
|
22
|
-
|
|
23
|
-
1. List which surfaces should become glass (cards, chips, floating controls,
|
|
24
|
-
bars you draw yourself).
|
|
25
|
-
2. For each one, decide the shape, how prominent it is, and whether it is
|
|
26
|
-
interactive.
|
|
27
|
-
3. Put glass elements that sit together inside one `GlassEffectContainer`.
|
|
28
|
-
4. Add `.glassEffect()` once padding, frame and styling are in place.
|
|
29
|
-
5. Add `.interactive()` only to elements that can be tapped or focused.
|
|
30
|
-
6. Where elements appear, disappear or rearrange with animation, give them
|
|
31
|
-
`glassEffectID(_:in:)` so they morph.
|
|
32
|
-
7. Wrap all of it in an `#available(iOS 26, *)` check, with a fallback look.
|
|
19
|
+
Detail lives in two references:
|
|
33
20
|
|
|
34
|
-
|
|
21
|
+
- [references/liquid-glass.md](references/liquid-glass.md): SwiftUI
|
|
22
|
+
signatures, morphing, unions, concentric shapes, custom bars, examples.
|
|
23
|
+
- [references/uikit-glass.md](references/uikit-glass.md): `UIGlassEffect`,
|
|
24
|
+
`UIGlassContainerEffect`, scroll edge effects, background extension, glass
|
|
25
|
+
button configurations and corner configuration in UIKit.
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
3. Buttons that imitate glass by hand become `.buttonStyle(.glass)` or
|
|
40
|
-
`.buttonStyle(.glassProminent)`.
|
|
41
|
-
4. Wherever items animate in or out, add morphing.
|
|
27
|
+
Bars, tab bars and toolbar layout (minimize behavior, bottom accessory,
|
|
28
|
+
`ToolbarSpacer`, search tab) are covered in `hig-components-layout`; motion in
|
|
29
|
+
`swiftui-animation`.
|
|
42
30
|
|
|
43
|
-
|
|
31
|
+
## Decide before writing code
|
|
44
32
|
|
|
45
|
-
|
|
33
|
+
### Glass belongs to the navigation layer
|
|
46
34
|
|
|
47
|
-
|
|
35
|
+
Liquid Glass is a functional layer for controls and navigation that floats
|
|
36
|
+
above content. Apple's Human Interface Guidelines say not to use it in the
|
|
37
|
+
content layer: cards, list rows and app backgrounds take a standard material
|
|
38
|
+
or a solid fill instead. The exception is a content-layer control with a
|
|
39
|
+
transient interactive part, such as a slider knob or toggle, which turns to
|
|
40
|
+
glass only while someone is using it. Standard sliders and toggles already do
|
|
41
|
+
this.
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
Use custom glass sparingly, on the few functional elements that matter most
|
|
44
|
+
(a floating action, a custom bar, a media control strip).
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
`DefaultGlassEffectShape()`, a capsule). Called bare, it gives regular glass in
|
|
53
|
-
a capsule.
|
|
46
|
+
### Regular or clear
|
|
54
47
|
|
|
55
|
-
|
|
48
|
+
| Variant | Use it for | Notes |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `.regular` | Almost everything; any component with a fair amount of text (alerts, sidebars, popovers) or over content that may hurt legibility | Blurs and adjusts luminosity behind it; most system components use it |
|
|
51
|
+
| `.clear` | Only components floating over visually rich media, such as photos and video | Highly translucent; needs a dimming layer when the media behind it is bright |
|
|
52
|
+
| `.identity` | Switching glass off conditionally without changing the view tree | No effect |
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
| `.identity` | No effect at all; useful for switching glass off conditionally |
|
|
54
|
+
For clear glass over bright content, HIG recommends a dark dimming layer at
|
|
55
|
+
35% opacity behind the component. Over content that is already dark, or with
|
|
56
|
+
AVKit's standard playback controls (which bring their own dimming), no dimming
|
|
57
|
+
layer is needed. See the example in the reference.
|
|
62
58
|
|
|
63
|
-
|
|
64
|
-
prominence, `.interactive(_:)` makes it respond to touch and pointer.
|
|
65
|
-
|
|
66
|
-
```swift
|
|
67
|
-
.glassEffect(.regular.tint(.teal).interactive())
|
|
68
|
-
```
|
|
59
|
+
### Keep the old look for a release
|
|
69
60
|
|
|
70
|
-
|
|
61
|
+
`UIDesignRequiresCompatibility` (Info.plist Boolean, iOS 26) set to `YES` runs
|
|
62
|
+
the app in a compatibility mode that looks as it did with the previous SDKs.
|
|
63
|
+
Apple marks it as temporary, for use while reviewing the UI, and the system
|
|
64
|
+
ignores the key once the app is built for iOS, iPadOS, macOS, Mac Catalyst or
|
|
65
|
+
tvOS 27 or later. Treat it as a bridge, not a plan.
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
they can blend into each other and morph between shapes.
|
|
67
|
+
## Workflow
|
|
74
68
|
|
|
75
|
-
|
|
76
|
-
equal to or larger than the spacing of the layout inside, so shapes merge while
|
|
77
|
-
they move but stay separate at rest.
|
|
69
|
+
### Implement
|
|
78
70
|
|
|
79
|
-
|
|
71
|
+
1. List the surfaces that are truly navigation or controls. Content stays out.
|
|
72
|
+
2. For each: shape, prominence (tint only for a primary action or status), and
|
|
73
|
+
whether it is interactive.
|
|
74
|
+
3. Put glass elements that sit together in one `GlassEffectContainer`.
|
|
75
|
+
4. Apply `.glassEffect()` after the modifiers that set size and look
|
|
76
|
+
(`font`, `foregroundStyle`, `padding`, `frame`).
|
|
77
|
+
5. Add `.interactive()` only to elements people can tap or focus.
|
|
78
|
+
6. Give elements that appear, disappear or rearrange a `glassEffectID(_:in:)`
|
|
79
|
+
inside a shared container and animate the state change.
|
|
80
|
+
7. Gate with `#available(iOS 26, *)` and give older systems a material
|
|
81
|
+
fallback of the same shape.
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
| --- | --- |
|
|
83
|
-
| `glassEffectID(_:in:)` | Names a shape within a namespace so animation can morph it |
|
|
84
|
-
| `glassEffectUnion(id:namespace:)` | Several views drawn as one combined glass shape |
|
|
85
|
-
| `glassEffectTransition(_:)` | How glass appears and disappears |
|
|
83
|
+
### Improve an existing screen
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
1. Remove custom backgrounds behind system bars, tab bars, split views and
|
|
86
|
+
sheets; they sit on top of the glass and break the scroll edge effect.
|
|
87
|
+
2. Replace hand-made blur behind controls with `.glassEffect()` or the glass
|
|
88
|
+
button styles; replace glass on content cards with a material.
|
|
89
|
+
3. Align nested corners with `ConcentricRectangle` instead of guessed radii.
|
|
90
|
+
4. Group sibling glass in a container and add morphing where items animate.
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
shapes are within the container's spacing).
|
|
91
|
-
- `.materialize`: fade the content and animate the glass in or out, without
|
|
92
|
-
matching geometry.
|
|
93
|
-
- `.identity`: no transition.
|
|
92
|
+
### Review
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
Go through the checklist at the end, item by item.
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
Button("Send", systemImage: "paperplane") { send() }
|
|
99
|
-
.buttonStyle(.glass)
|
|
100
|
-
|
|
101
|
-
Button("Book now") { book() }
|
|
102
|
-
.buttonStyle(.glassProminent)
|
|
103
|
-
```
|
|
96
|
+
## SwiftUI API at a glance
|
|
104
97
|
|
|
105
|
-
|
|
98
|
+
| API | Purpose |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `glassEffect(_:in:)` | Glass behind a view; default `.regular` in a capsule |
|
|
101
|
+
| `Glass.regular`, `.clear`, `.identity`; `.tint(_:)`, `.interactive(_:)` | Variant, color for prominence, touch response |
|
|
102
|
+
| `GlassEffectContainer(spacing:content:)` | Renders child glass in one pass so shapes blend and morph |
|
|
103
|
+
| `glassEffectID(_:in:)` | Stable identity for morphing between states |
|
|
104
|
+
| `glassEffectUnion(id:namespace:)` | Several views drawn as one glass shape |
|
|
105
|
+
| `glassEffectTransition(_:)` | `.matchedGeometry`, `.materialize`, `.identity` |
|
|
106
|
+
| `.buttonStyle(.glass)`, `.buttonStyle(.glassProminent)` | Glass buttons; prominent for the one primary action |
|
|
107
|
+
| `ConcentricRectangle`, `containerShape(_:)` | Corners concentric with the container or device |
|
|
108
|
+
| `safeAreaBar(edge:alignment:spacing:content:)` | Custom bar that insets the safe area and extends the scroll edge effect |
|
|
109
|
+
| `scrollEdgeEffectStyle(_:for:)`, `scrollEdgeEffectHidden(_:for:)` | Soft or hard edge where content meets floating controls |
|
|
110
|
+
| `backgroundExtensionEffect()` | Mirrors and blurs a view under a sidebar or inspector |
|
|
111
|
+
|
|
112
|
+
All of these need iOS 26.
|
|
106
113
|
|
|
107
114
|
```swift
|
|
108
|
-
|
|
109
|
-
.
|
|
115
|
+
Label("Flag", systemImage: "flag.fill")
|
|
116
|
+
.font(.headline)
|
|
117
|
+
.padding()
|
|
118
|
+
.glassEffect(.regular.tint(.orange).interactive())
|
|
110
119
|
```
|
|
111
120
|
|
|
112
|
-
|
|
113
|
-
meets a floating bar at a scroll edge.
|
|
114
|
-
|
|
115
|
-
`.backgroundExtensionEffect()` extends a view past the safe area by drawing
|
|
116
|
-
mirrored, blurred copies of it at the edges. A hero image in a split view's
|
|
117
|
-
detail column can then continue underneath the sidebar.
|
|
121
|
+
### Modifier order
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
`glassEffect` sizes its shape from the frame at the point where it is applied.
|
|
124
|
+
Appearance and layout modifiers come first, glass last:
|
|
120
125
|
|
|
121
126
|
```swift
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
Text("Gate B12")
|
|
128
|
+
.font(.headline)
|
|
129
|
+
.foregroundStyle(.primary)
|
|
130
|
+
.padding()
|
|
131
|
+
.glassEffect(in: .rect(cornerRadius: 16))
|
|
127
132
|
```
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
Applied before `.padding()`, the glass hugs the text and comes out too small.
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
### A gated glass card
|
|
136
|
+
### Concentric corners
|
|
134
137
|
|
|
135
138
|
```swift
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
var body: some View {
|
|
140
|
-
let label = Text(title).font(.headline).padding(20)
|
|
141
|
-
|
|
142
|
-
if #available(iOS 26, *) {
|
|
143
|
-
let tappable = Glass.regular.interactive()
|
|
144
|
-
label.glassEffect(tappable, in: .rect(cornerRadius: 18))
|
|
145
|
-
} else {
|
|
146
|
-
label.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 18))
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
139
|
+
VStack { content }
|
|
140
|
+
.padding(12)
|
|
141
|
+
.background(.thinMaterial, in: ConcentricRectangle())
|
|
150
142
|
```
|
|
151
143
|
|
|
152
|
-
|
|
144
|
+
`ConcentricRectangle()` computes each corner from the nearest container shape
|
|
145
|
+
(the device corners, a sheet, or any view that sets `containerShape(_:)` with a
|
|
146
|
+
rounded rectangular shape). Use `.concentric(minimum:)` corner styles so the
|
|
147
|
+
corner stays rounded when the container is far away or square.
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
move toward each other.
|
|
149
|
+
## UIKit at a glance
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
ForEach(symbols, id: \.self) { symbol in
|
|
167
|
-
Image(systemName: symbol)
|
|
168
|
-
.font(.title2)
|
|
169
|
-
.frame(width: 60, height: 60)
|
|
170
|
-
.glassEffect(.regular.interactive())
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
```
|
|
151
|
+
| API | Purpose |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `UIVisualEffectView(effect: UIGlassEffect(style: .regular))` | A glass view; `isInteractive`, `tintColor` |
|
|
154
|
+
| `UIGlassContainerEffect` with `spacing` | Combines nested glass effect views into one rendering |
|
|
155
|
+
| `UIScrollView.topEdgeEffect` (and bottom, left, right) | Per-edge `UIScrollEdgeEffect` with `style` and `isHidden` |
|
|
156
|
+
| `UIScrollEdgeElementContainerInteraction` | Lets a custom overlay shape the scroll edge effect |
|
|
157
|
+
| `UIBackgroundExtensionView` | Extends content under sidebars and inspectors |
|
|
158
|
+
| `UIButton.Configuration.glass()`, `.prominentGlass()`, `.clearGlass()`, `.prominentClearGlass()` | Glass buttons |
|
|
159
|
+
| `UIView.cornerConfiguration` with `UICornerConfiguration` | Fixed or container-concentric corners |
|
|
177
160
|
|
|
178
|
-
|
|
161
|
+
Code and details: [references/uikit-glass.md](references/uikit-glass.md).
|
|
179
162
|
|
|
180
|
-
|
|
181
|
-
@available(iOS 26, *)
|
|
182
|
-
struct ExpandingActions: View {
|
|
183
|
-
@Namespace private var glassSpace
|
|
184
|
-
@State private var expanded = false
|
|
185
|
-
|
|
186
|
-
var body: some View {
|
|
187
|
-
let gap: CGFloat = 36
|
|
188
|
-
return GlassEffectContainer(spacing: gap) {
|
|
189
|
-
HStack(spacing: gap) {
|
|
190
|
-
Button("Compose", systemImage: "square.and.pencil") {
|
|
191
|
-
withAnimation(.bouncy) { expanded.toggle() }
|
|
192
|
-
}
|
|
193
|
-
.buttonStyle(.glass)
|
|
194
|
-
.glassEffectID("compose", in: glassSpace)
|
|
195
|
-
|
|
196
|
-
if expanded {
|
|
197
|
-
Button("Attach", systemImage: "paperclip") { }
|
|
198
|
-
.buttonStyle(.glass)
|
|
199
|
-
.glassEffectID("attach", in: glassSpace)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Merging selected shapes with a union
|
|
163
|
+
## Fallback before iOS 26
|
|
208
164
|
|
|
209
165
|
```swift
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return GlassEffectContainer(spacing: gap) {
|
|
218
|
-
HStack(spacing: gap) {
|
|
219
|
-
ForEach(filters.indices, id: \.self) { index in
|
|
220
|
-
Text(filters[index])
|
|
221
|
-
.padding(.horizontal, 14)
|
|
222
|
-
.padding(.vertical, 8)
|
|
223
|
-
.glassEffect()
|
|
224
|
-
.glassEffectUnion(id: index < 2 ? "short" : "long", namespace: chipSpace)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
166
|
+
extension View {
|
|
167
|
+
@ViewBuilder
|
|
168
|
+
func floatingSurface(cornerRadius: CGFloat = 16) -> some View {
|
|
169
|
+
if #available(iOS 26, *) {
|
|
170
|
+
glassEffect(in: .rect(cornerRadius: cornerRadius))
|
|
171
|
+
} else {
|
|
172
|
+
background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: cornerRadius))
|
|
227
173
|
}
|
|
228
174
|
}
|
|
229
175
|
}
|
|
230
176
|
```
|
|
231
177
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
178
|
+
Custom glass surfaces fall back to a material of the same shape; glass button
|
|
179
|
+
styles fall back to `.bordered` or `.borderedProminent`. Do not imitate glass
|
|
180
|
+
with gradients and strokes. Standard materials (`.ultraThinMaterial` through `.thickMaterial`)
|
|
181
|
+
remain the right choice for the content layer on iOS 26 as well.
|
|
182
|
+
|
|
183
|
+
## Accessibility and system settings
|
|
184
|
+
|
|
185
|
+
- People can pick a preferred Liquid Glass look in Settings, and can turn on
|
|
186
|
+
Reduce Transparency, Increase Contrast or Reduce Motion. Each can change or
|
|
187
|
+
remove glass effects. System components adapt by themselves; custom glass,
|
|
188
|
+
colors and animations need checking under each.
|
|
189
|
+
- Reduce Transparency removes or reduces the translucency. Text and icons on
|
|
190
|
+
custom glass must still read; read `accessibilityReduceTransparency` in SwiftUI or
|
|
191
|
+
`UIAccessibility.isReduceTransparencyEnabled` in UIKit when a custom surface
|
|
192
|
+
needs a solid fallback.
|
|
193
|
+
- Increase Contrast (`colorSchemeContrast == .increased`) changes how glass
|
|
194
|
+
and system colors render. Custom tints need light, dark and
|
|
195
|
+
increased-contrast variants in the asset catalog.
|
|
196
|
+
- Reduce Motion tones down morphing; the interface must still make sense with
|
|
197
|
+
instant changes.
|
|
198
|
+
- Tint sparingly: color the background of the one primary action, not the
|
|
199
|
+
symbols on many controls. Toolbars and tab bars default to monochrome
|
|
200
|
+
symbols that flip between dark and light with the content behind them.
|
|
201
|
+
|
|
202
|
+
Testing the matrix of settings with screenshots belongs to
|
|
203
|
+
`ios-design-review`; implementation detail for each setting is in
|
|
204
|
+
`ios-accessibility`.
|
|
251
205
|
|
|
252
206
|
## Common mistakes
|
|
253
207
|
|
|
254
|
-
1. **Glass
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
3.
|
|
260
|
-
|
|
261
|
-
4. **Glass before padding or frame.** The
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
208
|
+
1. **Glass on content.** Cards, rows and backgrounds made of glass muddle the
|
|
209
|
+
hierarchy. Use a material or a solid color.
|
|
210
|
+
2. **Clear glass over plain backgrounds, or bright media without dimming.**
|
|
211
|
+
Clear is only for rich media, and needs the 35% dimming layer when the
|
|
212
|
+
media is bright.
|
|
213
|
+
3. **Custom backgrounds behind system bars.** They cover the glass and the
|
|
214
|
+
scroll edge effect. Remove them.
|
|
215
|
+
4. **Glass before padding or frame.** The shape comes out too small.
|
|
216
|
+
5. **Nested `GlassEffectContainer`s.** Not a documented pattern; keep one
|
|
217
|
+
container per group of neighbouring glass.
|
|
218
|
+
6. **`.interactive()` on decoration.** It promises a press that never comes.
|
|
219
|
+
7. **Glass stacked on glass.** Apple advises against layering Liquid Glass
|
|
220
|
+
elements on top of each other; group neighbours in a container instead.
|
|
221
|
+
8. **No availability gate or fallback.**
|
|
222
|
+
9. **Relying on `UIDesignRequiresCompatibility` long term.** It stops working
|
|
223
|
+
once the app builds for 27.
|
|
268
224
|
|
|
269
225
|
## Review checklist
|
|
270
226
|
|
|
271
|
-
- [ ]
|
|
272
|
-
- [ ]
|
|
273
|
-
- [ ] `.glassEffect()` placed after
|
|
274
|
-
- [ ]
|
|
275
|
-
- [ ] `
|
|
276
|
-
- [ ]
|
|
277
|
-
- [ ]
|
|
278
|
-
- [ ]
|
|
279
|
-
- [ ]
|
|
280
|
-
- [ ]
|
|
281
|
-
- [ ]
|
|
227
|
+
- [ ] Glass only on navigation and controls; content uses materials or fills
|
|
228
|
+
- [ ] `.clear` only over rich media, with a 35% dark dimming layer when the media is bright
|
|
229
|
+
- [ ] `.glassEffect()` placed after appearance and layout modifiers
|
|
230
|
+
- [ ] Neighbouring glass grouped in one `GlassEffectContainer`, none nested
|
|
231
|
+
- [ ] `.interactive()` only where people can interact
|
|
232
|
+
- [ ] Morphing uses `glassEffectID` with a `@Namespace` and an animated change
|
|
233
|
+
- [ ] Glass buttons use `.glass` / `.glassProminent` (or the UIKit glass configurations); one prominent action per screen
|
|
234
|
+
- [ ] Nested corners use `ConcentricRectangle` or `cornerConfiguration`, not guessed radii
|
|
235
|
+
- [ ] No custom backgrounds behind system bars; custom bars use `safeAreaBar` or the UIKit edge element interaction
|
|
236
|
+
- [ ] `#available(iOS 26, *)` gate with a same-shape material fallback
|
|
237
|
+
- [ ] Checked with Reduce Transparency, Increase Contrast and Reduce Motion
|
|
238
|
+
- [ ] `UIDesignRequiresCompatibility`, if present, has a removal plan before the 27 SDK
|
|
282
239
|
|
|
283
240
|
## References
|
|
284
241
|
|
|
285
|
-
- [references/liquid-glass.md](references/liquid-glass.md)
|
|
286
|
-
- [
|
|
287
|
-
- [
|
|
242
|
+
- [references/liquid-glass.md](references/liquid-glass.md)
|
|
243
|
+
- [references/uikit-glass.md](references/uikit-glass.md)
|
|
244
|
+
- [HIG: Materials](https://developer.apple.com/design/human-interface-guidelines/materials)
|
|
245
|
+
- [Adopting Liquid Glass](https://developer.apple.com/documentation/technologyoverviews/adopting-liquid-glass)
|
|
246
|
+
- [Applying Liquid Glass to custom views](https://developer.apple.com/documentation/swiftui/applying-liquid-glass-to-custom-views)
|
|
247
|
+
- [UIDesignRequiresCompatibility](https://developer.apple.com/documentation/bundleresources/information-property-list/uidesignrequirescompatibility)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "swiftui-liquid-glass",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 0,
|
|
6
|
+
"name": "glass-in-content-layer",
|
|
7
|
+
"prompt": "Our travel app is moving to the iOS 26 SDK. The designer wants every booking card in the trips list to be Liquid Glass, the tab bar to keep our brand-red background image, and a floating 'New trip' button bottom right. Deployment target is iOS 17. Write the SwiftUI for the card, the button and whatever we do with the tab bar.",
|
|
8
|
+
"expected_output": "Pushes back on glass for the booking cards because they are content: they get a standard material or solid background. Removes the custom tab bar background so the system glass and scroll edge effect work. Builds the floating action with glass (a glass or glassProminent button style or glassEffect with interactive), applies glassEffect after padding and frame, gates everything with #available(iOS 26, *) and provides an ultraThinMaterial fallback of the same shape for iOS 17 to 25.",
|
|
9
|
+
"files": [],
|
|
10
|
+
"expectations": [
|
|
11
|
+
"Says the booking cards are content and should use a material or solid fill rather than Liquid Glass",
|
|
12
|
+
"Removes or advises removing the custom tab bar background image so system glass and the scroll edge effect are not covered",
|
|
13
|
+
"Uses .buttonStyle(.glassProminent) or .glass, or glassEffect with .interactive(), for the floating button",
|
|
14
|
+
"Places glassEffect after padding/frame/appearance modifiers in any custom glass code",
|
|
15
|
+
"Gates iOS 26 APIs with #available(iOS 26, *) and gives a same-shape material fallback for older versions"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 1,
|
|
20
|
+
"name": "clear-glass-over-photo",
|
|
21
|
+
"prompt": "Full-screen photo viewer, SwiftUI, iOS 26 only. I want share / favorite / delete buttons floating over the photo and I want them as see-through as possible. Some photos are snow scenes and the white icons vanish. Which glass variant, and how do I fix the legibility?",
|
|
22
|
+
"expected_output": "Chooses Glass.clear because the controls float over rich media, and explains that clear needs a dimming layer when the content behind is bright: a dark layer around 35% opacity (black.opacity(0.35)) under the controls, per HIG, which can be skipped for dark photos. Groups the buttons in a GlassEffectContainer, uses interactive glass or glass button styles, and mentions checking Reduce Transparency and Increase Contrast. Notes .regular is the fallback choice when legibility cannot be guaranteed.",
|
|
23
|
+
"files": [],
|
|
24
|
+
"expectations": [
|
|
25
|
+
"Picks .clear glass for controls over the photo",
|
|
26
|
+
"Adds a dark dimming layer of about 35% opacity behind the clear glass when the photo is bright",
|
|
27
|
+
"Groups the floating buttons in one GlassEffectContainer",
|
|
28
|
+
"Mentions Reduce Transparency and/or Increase Contrast testing for the custom glass",
|
|
29
|
+
"Mentions .regular as the safer variant when the background cannot be controlled or text is heavy"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 2,
|
|
34
|
+
"name": "uikit-adoption-and-opt-out",
|
|
35
|
+
"prompt": "We have a big UIKit app (UINavigationController, custom bottom action bar over a UITableView, hand-made blur buttons). We are not ready for the new look in this release. Can we just ship on Xcode 26 and switch the design off? And for the next release, what UIKit APIs replace our blur buttons and make the custom bottom bar behave like a system toolbar?",
|
|
36
|
+
"expected_output": "Explains UIDesignRequiresCompatibility in Info.plist set to YES keeps the previous look while building with the 26 SDK, that Apple calls it temporary and that it is ignored once the app is built with the 27 SDKs. For the next release: UIButton.Configuration.glass() / prominentGlass() or UIVisualEffectView with UIGlassEffect for the buttons, UIGlassContainerEffect to group them, UIScrollEdgeElementContainerInteraction on the bottom bar container with scrollView and edge = .bottom so the scroll edge effect follows it, removal of custom bar backgrounds, and a pre-26 UIBlurEffect fallback.",
|
|
37
|
+
"files": [],
|
|
38
|
+
"expectations": [
|
|
39
|
+
"Names UIDesignRequiresCompatibility as the Info.plist opt-out",
|
|
40
|
+
"States the key is temporary and ignored when building for the 27 SDKs",
|
|
41
|
+
"Replaces the blur buttons with UIButton.Configuration glass configurations or UIGlassEffect in a UIVisualEffectView",
|
|
42
|
+
"Uses UIScrollEdgeElementContainerInteraction (scrollView plus edge) for the custom bottom bar",
|
|
43
|
+
"Mentions UIGlassContainerEffect for grouping neighbouring glass elements"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[
|
|
2
|
+
{"query": "how do i make a floating circular button with the new liquid glass look in swiftui, ios 26", "should_trigger": true},
|
|
3
|
+
{"query": "GlassEffectContainer spacing - my two glass chips don't merge when I animate them together, what am I missing", "should_trigger": true},
|
|
4
|
+
{"query": "designer says use 'clear glass' for the video player controls, but the white icons are unreadable on bright scenes. fix?", "should_trigger": true},
|
|
5
|
+
{"query": "UIKit app, need the iOS 26 glass material on a custom UIView overlay, is there a UIGlassEffect or something", "should_trigger": true},
|
|
6
|
+
{"query": "can we ship with Xcode 26 but keep the iOS 18 look for one more release? our QA hasn't reviewed the new design", "should_trigger": true},
|
|
7
|
+
{"query": "is it ok to make every card in my feed a glassEffect? it looks cool in the simulator", "should_trigger": true},
|
|
8
|
+
{"query": "nested corner radius on a sheet's inner panel never matches the sheet curve, any API for concentric corners in swiftui 26", "should_trigger": true},
|
|
9
|
+
{"query": "custom bottom composer bar over a ScrollView: how do I get the same blur/fade under it as the system toolbar has", "should_trigger": true},
|
|
10
|
+
{"query": "what should glass fall back to on iOS 17 devices, our min target is 17", "should_trigger": true},
|
|
11
|
+
{"query": "with Reduce Transparency on, my custom glass map controls are unreadable over satellite imagery", "should_trigger": true},
|
|
12
|
+
{"query": "tab bar shrinks when I scroll on iOS 26, how do I stop that or make it shrink only on scroll down", "should_trigger": false},
|
|
13
|
+
{"query": "where do I put a mini player above the tab bar in SwiftUI like Apple Music", "should_trigger": false},
|
|
14
|
+
{"query": "make my app icon work with the new clear and tinted home screen modes in Icon Composer", "should_trigger": false},
|
|
15
|
+
{"query": "animate a card expanding into a detail screen with a hero transition", "should_trigger": false},
|
|
16
|
+
{"query": "SF Symbol draw-on animation for a checkmark when the upload completes", "should_trigger": false},
|
|
17
|
+
{"query": "add a haptic tap when the user toggles favorite", "should_trigger": false},
|
|
18
|
+
{"query": "frosted glass blur effect on a web page header with CSS backdrop-filter", "should_trigger": false},
|
|
19
|
+
{"query": "review the dark mode and Dynamic Type screenshots of our checkout screen against the HIG", "should_trigger": false},
|
|
20
|
+
{"query": "Jetpack Compose: translucent blurred top app bar like iOS", "should_trigger": false},
|
|
21
|
+
{"query": "parallax header that scales as I scroll a list in SwiftUI", "should_trigger": false}
|
|
22
|
+
]
|