fix(client/apple): the tray blur keeps its shape, and the tab pill turns to glass
ci / bun-nix (pull_request) Successful in 27s
ci / docs-site (pull_request) Successful in 1m4s
ci / web (pull_request) Successful in 1m9s
ci / rust-arm64 (pull_request) Successful in 1m30s
apple / swift (pull_request) Successful in 1m35s
apple / screenshots (pull_request) Skipped
ci / rust (pull_request) Canceled after 4m39s
ci / bun-nix (pull_request) Successful in 27s
ci / docs-site (pull_request) Successful in 1m4s
ci / web (pull_request) Successful in 1m9s
ci / rust-arm64 (pull_request) Successful in 1m30s
apple / swift (pull_request) Successful in 1m35s
apple / screenshots (pull_request) Skipped
ci / rust (pull_request) Canceled after 4m39s
Two follow-ups from the second on-glass pass: - The tray blur's pop-in survived the geometryGroup: the full-bleed growth (negative padding + safe-area expansion) rode the push's transaction, and safe-area resolution sits outside a geometry group. The scrim now pins its own geometry out of any animation - the layer fade/slide still carries it, only its SHAPE can never animate. The bottom overshoot grows 32 -> 72 pt (the tray sits over scrolling rows plus the detail line; the blur influence starts well above the legend now) and the mask holds strength longer before dissolving. - The selected tab pill is a Liquid Glass surface (accent-tinted through consoleGlass, material fallback pre-26/tvOS) - the strip wears the same material language as the rows below it. The matched-geometry travel between pills is unchanged.
This commit is contained in:
@@ -385,15 +385,23 @@ struct GamepadTrayScrim: View {
|
||||
LinearGradient(
|
||||
stops: [
|
||||
.init(color: .black, location: 0),
|
||||
.init(color: .black.opacity(0.9), location: 0.5),
|
||||
.init(color: .black.opacity(0.92), location: 0.55),
|
||||
.init(color: .clear, location: 1),
|
||||
],
|
||||
startPoint: fromEdge, endPoint: toContent)
|
||||
}
|
||||
// Grow past the tray so the fade-to-clear happens OUTSIDE its bounds — the tray's own
|
||||
// text always sits on the strong part, rows blur out before they reach it.
|
||||
.padding(edge == .top ? .bottom : .top, -32)
|
||||
// text always sits on the strong part, rows blur out before they reach it. The bottom
|
||||
// gets the longer runway: its tray sits over SCROLLING rows plus the detail line, and
|
||||
// the field verdict on the short reach was rows colliding visibly with the legend.
|
||||
.padding(edge == .top ? .bottom : .top, edge == .top ? -44 : -72)
|
||||
.ignoresSafeArea()
|
||||
// This view's geometry must NEVER animate: mounted inside a pushed shell layer, the
|
||||
// full-bleed growth above (the negative padding and the safe-area expansion) rode the
|
||||
// push's transaction, so the blur visibly entered at content bounds and grew into
|
||||
// place — and `.geometryGroup()` on the layer does not reach safe-area resolution.
|
||||
// The layer's own fade/slide still carries the scrim; only its SHAPE is pinned.
|
||||
.transaction { $0.animation = nil }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,10 +124,10 @@ struct GamepadHomeView: View {
|
||||
#if os(iOS)
|
||||
if let screen = topScreen {
|
||||
screenLayer(screen)
|
||||
// Resolve the screen's internal layout (safe-area trays, the scrims'
|
||||
// `.ignoresSafeArea()` full-bleed) BEFORE the insertion animates: without
|
||||
// this the tray blurs entered at their content bounds and visibly grew to
|
||||
// the screen edges mid-push.
|
||||
// Settle the screen's internal layout before the insertion animates, so
|
||||
// descendants never lerp from a half-resolved first frame. (Not sufficient
|
||||
// for the tray blurs on its own — safe-area expansion resolves outside a
|
||||
// geometry group; GamepadTrayScrim pins its own geometry too.)
|
||||
.geometryGroup()
|
||||
.zIndex(1)
|
||||
.id(screen.id)
|
||||
|
||||
@@ -257,10 +257,12 @@ struct GamepadSettingsView: View {
|
||||
.padding(.vertical, 7)
|
||||
.background {
|
||||
// One shared capsule that MOVES between pills, rather than one per pill fading
|
||||
// in and out — the highlight travels the way the press did.
|
||||
// in and out — the highlight travels the way the press did. A Liquid Glass
|
||||
// surface (accent-tinted through consoleGlass), so the strip wears the same
|
||||
// material language as the rows it sits above.
|
||||
if selected {
|
||||
Capsule()
|
||||
.fill(ink.accent(0.85))
|
||||
Color.clear
|
||||
.consoleGlass(Capsule(), tint: ink.accent(0.85))
|
||||
.matchedGeometryEffect(id: "tab", in: tabHighlight)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user