Skip to content

Jetpack login prologue: top gradient fade disappears after backgrounding the app #25651

Description

@jkmassel

Summary

On the Jetpack login prologue, the gradient that fades out the scrolling word-list at the top of the screen disappears after the app is backgrounded and brought back to the foreground. It only reappears after a force-quit + relaunch.

Steps to reproduce

  1. Launch Jetpack to the signed-out login prologue.
  2. Note the scrolling word-list fading out toward the top of the screen (around/behind the logos).
  3. Switch to another app, then immediately switch back to Jetpack.
  4. The top fade is gone — the word-list renders sharp and full-opacity all the way to the top edge.
  5. Force-quit and relaunch — the fade is restored.

Expected

The top gradient fade persists across background → foreground.

Actual

The fade vanishes after a single background → foreground cycle and stays gone until the app is force-quit.

Root cause

JetpackPrologueViewController.traitCollectionDidChange(_:) recreates gradientLayer but never assigns its frame:

gradientLayer.removeFromSuperlayer()
gradientLayer = makeGradientLayer()       // frame == .zero
view.layer.insertSublayer(gradientLayer, above: jetpackAnimatedView.layer)

The frame is only set in viewDidLayoutSubviews (gradientLayer.frame = view.bounds). When the app is backgrounded, iOS renders snapshots in both light and dark appearances, firing traitCollectionDidChange with a userInterfaceStyle change. That recreates the gradient at a .zero frame, and on return there is no layout pass (bounds unchanged), so viewDidLayoutSubviews never runs — the gradient stays zero-sized and therefore invisible. Force-quitting re-runs viewDidLoadloadNewPrologueView(), which re-inserts the layer and triggers a layout pass, so it renders again.

Suggested fix

Set the frame immediately after recreating/inserting the layer (or trigger layout):

view.layer.insertSublayer(gradientLayer, above: jetpackAnimatedView.layer)
gradientLayer.frame = view.bounds   // or view.setNeedsLayout()

Better still: don't recreate the layer on every trait change — update its colors in place so it survives appearance changes without a frame round-trip.

Environment

  • iPhone Air, iOS 26.5.1
  • The root-cause code in JetpackPrologueViewController is long-standing and is not modified by the in-progress prologue replacement (Replace the login prologue in WordPressAuthenticator #25642), so this is expected to reproduce on trunk / App Store builds as well (not yet confirmed against an App Store build).

Screenshots

Fade present (cold launch / after force-quit) Fade gone (after background → foreground)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions