diff --git a/CHANGELOG.md b/CHANGELOG.md index d893c634d..8af85cdf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Next +- fix: skip capturing a snapshot during view controller transitions ([#265](https://github.com/PostHog/posthog-ios/pull/265)) + ## 3.15.8 - 2024-11-28 - no user facing changes diff --git a/PostHog/Replay/PostHogReplayIntegration.swift b/PostHog/Replay/PostHogReplayIntegration.swift index 095dd820f..de028626d 100644 --- a/PostHog/Replay/PostHogReplayIntegration.swift +++ b/PostHog/Replay/PostHogReplayIntegration.swift @@ -371,7 +371,8 @@ } private func toScreenshotWireframe(_ window: UIWindow) -> RRWireframe? { - if !window.isVisible() { + // this will bail on interactive animations (e.g edge slide) + if !window.isVisible() || isAnimatingTransition(window) { return nil } @@ -394,6 +395,11 @@ return wireframe } + /// Check if window's root view controller is animating a transition + private func isAnimatingTransition(_ window: UIWindow) -> Bool { + window.rootViewController?.transitionCoordinator?.isAnimated ?? false + } + private func isAssetsImage(_ image: UIImage) -> Bool { // https://github.com/daydreamboy/lldb_scripts#9-pimage // do not mask if its an asset image, likely not PII anyway diff --git a/PostHog/Replay/UIView+Util.swift b/PostHog/Replay/UIView+Util.swift index 08f713e3d..2bdd32fb1 100644 --- a/PostHog/Replay/UIView+Util.swift +++ b/PostHog/Replay/UIView+Util.swift @@ -54,7 +54,11 @@ let renderer = UIGraphicsImageRenderer(size: size, format: rendererFormat) let image = renderer.image { _ in - drawHierarchy(in: bounds, afterScreenUpdates: false) + // true for afterScreenUpdates so that we capture view *after* any pending animations are committed + // As a side effect, we need to pause view tracker temporarily to avoid recursive calls since this option will cause subviews to layout, which will then trigger another capture + ViewLayoutTracker.paused = true + drawHierarchy(in: bounds, afterScreenUpdates: true) + ViewLayoutTracker.paused = false } return image diff --git a/PostHog/Replay/ViewLayoutTracker.swift b/PostHog/Replay/ViewLayoutTracker.swift index d48029c09..4157f36a9 100644 --- a/PostHog/Replay/ViewLayoutTracker.swift +++ b/PostHog/Replay/ViewLayoutTracker.swift @@ -3,14 +3,17 @@ import UIKit enum ViewLayoutTracker { - static var hasChanges = false + static var paused = false + private(set) static var hasChanges = false private static var hasSwizzled = false static func viewDidLayout(view _: UIView) { + guard !paused else { return } hasChanges = true } static func clear() { + guard !paused else { return } hasChanges = false }