Skip to content

Fix app-breaking card-position regression from always-on floatingCardToolBarItems constraints#30

Merged
nighthawk merged 1 commit into
mainfrom
fix/floating-card-position-regression
Jun 20, 2026
Merged

Fix app-breaking card-position regression from always-on floatingCardToolBarItems constraints#30
nighthawk merged 1 commit into
mainfrom
fix/floating-card-position-regression

Conversation

@nighthawk

Copy link
Copy Markdown
Member

Fixes an app-breaking card-position regression in 2.5.0

floatingCardToolBarItems (2.5.0, #29) added cardFloatingView to the controller's root view in viewDidLoad and permanently pinned it to cardWrapperContent — the card's content wrapper — including a bottom == cardWrapperContent.bottom constraint. Those constraints were active for every card, even ones that provide no floating items.

Because the wrapper animates (its top/height constraints change) on push/pop, coupling a root-level view to it via that bottom constraint disrupted the card's position layout. After pushing then popping a card, the wrapper was left visually extended while cardWrapperDesiredTopConstraint — and therefore the computed cardPosition — read collapsed. Result: content faded out, map toolbar buttons showed (the map becomes interactive when not extended), and the card couldn't be dragged. It reproduced on plain cards that don't use the affordance at all (e.g. tap a stop → timetable card pushes → pop → wedged; needs a force-quit).

Fix

  1. Install lazily. cardFloatingView and its constraints are added only while a card actually has floatingCardToolBarItems, and torn down again otherwise. Cards without items now carry none of this layout — exactly as before 2.5.0. This alone resolves the regression for non-adopting cards.
  2. Decouple the bottom pin. Pin the bottom to the screen's safe area instead of cardWrapperContent.bottom. The card always reaches at or below the screen edge, so it's the same place visually, but it no longer couples to the wrapper as it animates — protecting adopting cards' own transitions too. Horizontal alignment stays relative to the card (that axis doesn't move during a vertical transition); the leading/trailing inequality clamps still keep a wide row from overflowing.

The agenda pill looks and behaves identically (the old "prefer card bottom, clamped to safe area" always resolved to the safe-area clamp anyway, since the card always reaches the screen edge).

Reviewer notes

  • No public API change — floatingCardToolBarItems / floatingCardToolBarAlignment are unchanged; only the internal install/teardown and the bottom-pin target changed.
  • Builds clean standalone (iOS Simulator) and full TripGo builds clean against this via a local package override.
  • Needs a 2.5.1 tag; TripGo's pin (currently 2.5.0, which ships the bug) must be bumped. This blocks merging the TripGo agenda umbrella PR (#101), which pins 2.5.0.
  • Runtime verification of the repro (push → pop a plain card) is best confirmed on device.

🤖 Generated with Claude Code

…nstraints

`floatingCardToolBarItems` (2.5.0) added `cardFloatingView` to the controller's
root view in `viewDidLoad` and *permanently* pinned it to `cardWrapperContent`
— the card's content wrapper — including a bottom constraint to the wrapper's
bottom edge. Those constraints were active for **every** card, even ones that
provide no floating items.

Because the wrapper animates (its top/height constraints change) on push/pop,
coupling a root-level view to it via that bottom constraint disrupted the
card's position layout: after pushing then popping a card, the wrapper could be
left visually extended while `cardWrapperDesiredTopConstraint` (and therefore
`cardPosition`) read collapsed — so the content faded out, the map buttons
showed, and the card couldn't be dragged. It reproduced on plain cards (e.g. a
timetable card) that don't use the affordance at all.

Two changes:
- Install `cardFloatingView` and its constraints lazily — only while a card
  actually has `floatingCardToolBarItems` — and remove them again otherwise.
  Cards without items now carry none of this layout, exactly as before 2.5.0.
- Pin the bottom to the screen's safe area instead of `cardWrapperContent`. The
  card always reaches at or below the screen edge, so it's the same place
  visually, but it no longer couples to the wrapper as it animates. Horizontal
  alignment stays relative to the card (its x/width don't move on a vertical
  transition).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nighthawk

Copy link
Copy Markdown
Member Author

Suggested squash-merge commit message:

fix: card-position breakage from always-on floatingCardToolBarItems constraints

2.5.0 pinned `cardFloatingView` to the animating `cardWrapperContent` for every
card (even ones with no floating items), which corrupted the card's position
layout on push/pop — leaving the wrapper visually extended while `cardPosition`
read collapsed (faded content, dead drag, map buttons showing), even on plain
cards that don't use the affordance.

Install the view and its constraints lazily — only while a card has
`floatingCardToolBarItems` — and pin its bottom to the screen safe area instead
of the card wrapper, decoupling it from the card's push/pop animation. No public
API change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

After merge: tag 2.5.1, then bump TripGo's TGCardViewController pin from 2.5.0 to 2.5.1 (2.5.0 ships this regression; it currently blocks the agenda umbrella PR tripgo-ios#101).

@nighthawk nighthawk added the bug Something isn't working label Jun 20, 2026
@nighthawk nighthawk self-assigned this Jun 20, 2026
@nighthawk nighthawk merged commit d6e2940 into main Jun 20, 2026
3 checks passed
@nighthawk nighthawk deleted the fix/floating-card-position-regression branch June 20, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant