Skip to content

fix(perry-ui-ios): finish #1107 — iOS 26 device rendering of Buttons + nested stack bg - #1127

Merged
proggeramlug merged 2 commits into
mainfrom
fix-ios26-rendering
May 19, 2026
Merged

fix(perry-ui-ios): finish #1107 — iOS 26 device rendering of Buttons + nested stack bg#1127
proggeramlug merged 2 commits into
mainfrom
fix-ios26-rendering

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Summary

Finishes the work started in #1109 for issue #1107 (partial-alpha NSColor renders zero glyphs on iOS 26 device). Three regressions / blind spots from #1109's first take remained, all reproduced on a physical iPhone running iOS 26.5:

  1. Text + textSetColor(α < 1.0) still painted nothing. fix(perry-ui-ios): #1107 partial-alpha text invisible on iOS 26 #1109 reused the label's borrowed view.font pointer and the un-retained initWithString:attributes: result. The working AttributedText path builds a fresh [UIFont systemFontOfSize:] from the label's current point size and retains the resulting NSAttributedString — this commit mirrors that exact pattern (apply_label_color_via_attributed).
  2. Bare Button("x", cb) + widgetSetBackgroundColor(...) rendered invisible. buttonWithType:UIButtonTypeSystem on iOS 26 routes through the Liquid Glass renderer, which overrides explicit setTitleColor: / setBackgroundColor: with the system tint. Switch to UIButtonTypeCustom, seed [UIColor labelColor] as the default title color so a bare button is still visible, and drop the setAttributedTitle:nil cleanup branch from fix(perry-ui-ios): #1107 partial-alpha text invisible on iOS 26 #1109 (on iOS 26 it nukes the button's plain-title rendering along with the attributed state, leaving even α==1.0 buttons blank).
  3. widgetSetBackgroundColor on a NESTED UIStackView painted transparent. UIStackView.backgroundColor is documented iOS 14+ but the property doesn't drive painting on inner stacks under iOS 26's compositor. The CALayer's own backgroundColor (CGColor) does paint reliably, so we set both — view-level for non-buggy paths (root stack, iOS 17 sim) and layer-level as the belt-and-suspenders fix.

Related: #1122 (follow-up audit of remaining iOS 26 regressions).

Repro / verification

Bisect of the Wishare Onboarding screen on iPhone running iOS 26.5:

Note: a separate Perry TS-compiler issue affects cross-module imports of {r,g,b,a} object literals — those still produce wrong values at textSetColor/widgetSetBackgroundColor call sites even with this PR applied. I'm filing that as a separate issue; this PR only fixes the iOS 26 native-side rendering bugs.

Test plan

  • Confirm bare Button with no explicit textSetColor still has visible text on light + dark mode (uses [UIColor labelColor] default)
  • Confirm Button with widgetSetBackgroundColor(α=1.0) + textSetColor(WHITE α=1.0) paints red bg + white title on iOS 26 device
  • Confirm Text with textSetColor(α=0.87) paints glyphs on iOS 26 device
  • Confirm nested VStack + widgetSetBackgroundColor(WHITE α=1.0) paints over a colored parent on iOS 26 device
  • Confirm iOS 17 simulator paths unchanged (root stack + bare buttons still render the same way)
  • CI green

…+ nested stack bg

PR #1109 shipped a partial fix for #1107 (partial-alpha NSColor renders
zero glyphs on iOS 26 device) but three regressions / blind spots
remained, all reproduced on physical iPhone running iOS 26.5:

1. Text widgets with `textSetColor(α < 1.0)` (e.g. Material's 87% black)
   still rendered nothing. #1109's `apply_label_color_via_attributed`
   reused the label's borrowed `view.font` pointer and the un-retained
   `initWithString:attributes:` result; the working AttributedText path
   builds a fresh `[UIFont systemFontOfSize:]` and retains the result.
   This commit mirrors that exact pattern.

2. Bare `Button("Mitmachen", cb)` + `widgetSetBackgroundColor(BRAND_RED)`
   rendered invisible. `buttonWithType:UIButtonTypeSystem` on iOS 26
   routes through the Liquid Glass renderer, which overrides explicit
   `setTitleColor:` / `setBackgroundColor:` with the system tint.
   Switch to `UIButtonTypeCustom` (and seed `[UIColor labelColor]` as
   the default title color so a bare button with no explicit color is
   still visible). Also drop the `setAttributedTitle:nil` cleanup branch
   from #1109 — on iOS 26 it nukes the button's plain-title rendering
   along with the attributed state, leaving even α==1.0 buttons blank.

3. `widgetSetBackgroundColor` on a NESTED `UIStackView` painted
   transparent. `UIStackView.backgroundColor` is documented iOS 14+ but
   the property doesn't drive painting on inner stacks under iOS 26's
   compositor. The CALayer's own `backgroundColor` (CGColor) does paint
   reliably, so set both — view-level for non-buggy paths (root stack,
   iOS 17 sim) and layer-level as the belt-and-suspenders fix.

Verified on iPhone running iOS 26.5: bisect of the Wishare Onboarding
screen (TEXT_PRIMARY α=0.87 labels, BRAND_RED-bg `Mitmachen` button,
white-bg nested card VStack) now renders all three widget classes.

Follow-up issue #1122 tracks the broader audit of iOS 26 regressions.
Lint job on PR #1127 failed on `cargo fmt --check`. Single extraneous
blank line between `set_background_color` and `gradient_bg_class`.
@proggeramlug
proggeramlug merged commit d15eb4f into main May 19, 2026
9 checks passed
@proggeramlug
proggeramlug deleted the fix-ios26-rendering branch May 19, 2026 15:58
proggeramlug added a commit that referenced this pull request May 21, 2026
…utton (#1284)

PR #1127 added a CALayer.backgroundColor fallback for UIStackView to
work around nested-stack transparency on iOS 26 device. UIButton has
the same class of bug — Liquid Glass renderer can override
setBackgroundColor: on certain button-type/configuration combinations
even after #1127 forced UIButtonTypeCustom. Apply the same
belt-and-suspenders fallback to UIButton so the CGColor lands on the
layer directly regardless of UIKit-side interception. No behavior
change for ordinary UIViews (setBackgroundColor: already updates
layer.backgroundColor on those).

Also rewrites the function's doc comment — it previously described an
"inserting a UIView pinned to stack bounds" fallback that the actual
implementation never did (we always set layer.backgroundColor with
CGColor). Documents both currently-known iOS 26 cases (UIStackView,
UIButton) and the rationale.

Closes #1122 pending on-device retest. Native side has now layered
#1109 (attributed-text for partial-alpha labels), #1127 (UIButtonTypeCustom +
UIStackView layer fallback), and this PR (UIButton layer fallback).
Underlying TS-compiler bug #1129 — which silently produced NaN/
undefined when the consumer app imported color object literals from
another module, masking all native-side fixes — was closed by #1281
(baaeb44).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant