fix(ios): stabilize blur intensity after mount with CADisplayLink#116
Conversation
UIKit can invalidate the paused blur animator during the first few transition frames after mount. Rebuild across a short bounded window so the correct material intensity is restored without a visible flash. Co-authored-by: Cursor <cursoragent@cursor.com>
📝 WalkthroughWalkthrough
ChangesBlur stabilization
Estimated code review effort: 3 (Moderate) | ~15–30 minutes Possibly related PRs
Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant UIWindow
participant BlurEffectView
participant CADisplayLink
UIWindow->>BlurEffectView: attach view
BlurEffectView->>BlurEffectView: rebuildAnimator()
BlurEffectView->>CADisplayLink: schedule stabilization
CADisplayLink->>BlurEffectView: handleStabilizationTick()
BlurEffectView->>BlurEffectView: rebuildAnimator()
BlurEffectView->>CADisplayLink: invalidate after frame budget
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
ios/Views/BlurEffectView.swift (1)
86-101: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winBreak the CADisplayLink retain cycle
CADisplayLink(target: self, ...)keepsBlurEffectViewalive throughstabilizationDisplayLink, so deallocation can be delayed until the 3-frame window ends. A weak proxy would letdeinitrun immediately if the view is removed or the app backgrounds mid-stabilization.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ios/Views/BlurEffectView.swift` around lines 86 - 101, Break the CADisplayLink retain cycle in startStabilizationIfNeeded by targeting a weak proxy object instead of BlurEffectView directly; have the proxy forward handleStabilizationTick to the view without retaining it, while preserving existing stabilizationDisplayLink invalidation and callback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@ios/Views/BlurEffectView.swift`:
- Around line 86-101: Break the CADisplayLink retain cycle in
startStabilizationIfNeeded by targeting a weak proxy object instead of
BlurEffectView directly; have the proxy forward handleStabilizationTick to the
view without retaining it, while preserving existing stabilizationDisplayLink
invalidation and callback behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5fd8cecb-8c4f-494e-9c72-2fd1a1087b0c
📒 Files selected for processing (1)
ios/Views/BlurEffectView.swift
|
nice work🚀 |
|
Well done! @kOOnzTe |
|
Released in 4.7.1 |
Summary
Stabilize
BlurEffectViewduring the first frames after mount, window attach, and foreground return.Problem
BlurEffectViewrelies on a pausedUIViewPropertyAnimatorto preserve custom blur intensity. In practice, UIKit can still invalidate that animator during the first few frames after:When that happens, the blur may briefly render with the wrong material state or appear unblurred until a later rebuild.
Solution
This change adds a short, bounded
CADisplayLinkstabilization pass:didMoveToWindowdeinitThis keeps the existing animator-based intensity approach, but makes it more resilient during UIKit transition timing.
Why this is safe
Testing
BlurEffectViewand verified blur stays applied on first render