Skip to content

Optimize native ad view layout updates and fix media content reassignment - #11

Open
Uhucream wants to merge 1 commit into
mainfrom
claude/ad-inspector-scroll-bug-zxcblg
Open

Optimize native ad view layout updates and fix media content reassignment#11
Uhucream wants to merge 1 commit into
mainfrom
claude/ad-inspector-scroll-bug-zxcblg

Conversation

@Uhucream

Copy link
Copy Markdown
Owner

Summary

This PR refactors the native ad element frame tracking and constraint management to improve performance and fix issues with media content reassignment. The changes replace anchor-based frame resolution with direct geometry measurement and optimize constraint updates to avoid unnecessary re-registration of ad assets.

Key Changes

  • Replaced anchor-based frame tracking with direct geometry measurement: Removed TypedAnchor and TypedAnchorBoundsPreferenceKey in favor of ElementFrame and ElementFramePreferenceKey. This eliminates window-relative coordinate arithmetic and provides more direct frame values measured in a dedicated coordinate space.

  • Introduced NativeAdvertisementCoordinateSpaceName: A dedicated type (rather than a string) for the ad container's coordinate space, preventing accidental resolution against similarly-named coordinate spaces in the host app.

  • Optimized constraint updates: Created ElementFittingConstraints struct to track individual constraints by role (leading, top, width, height). This enables in-place constant updates for moved elements instead of deactivating and recreating the entire constraint set on every frame change.

  • Implemented smart asset view change detection: Added hasChangedAssetViews flag to distinguish between elements being added/removed versus just repositioned. Re-registration of ad assets is now skipped when only positions change, avoiding redundant SDK work and preventing retrigger of debug UI.

  • Fixed media content reassignment: Added identity check (!==) before reassigning mediaView.mediaContent to prevent restarting playback when the content hasn't actually changed.

Notable Implementation Details

  • The ElementFittingConstraints struct allows constraint constants to be mutated in place, significantly reducing the overhead of layout updates for repositioned elements.
  • The preference key reduction logic properly handles updates to existing element frames by replacing them in-place rather than appending duplicates.
  • Asset view registration is now conditional on actual changes to the ad structure, not just frame updates, improving performance and stability.

https://claude.ai/code/session_01A2rtVf6eKThpce2C9eKaB6

…chors

overlayGeometry[$0.anchor] resolved each element's bounds by subtracting
the reading proxy's window-relative frame from the element's, so every
resolution while scrolling redid arithmetic on two large, scroll-dependent
doubles. The result carried last-digit floating point noise even though
nothing had actually moved, which updateUIView's exact CGRect comparison
treated as a real layout change on every frame and re-registered the ad
with the SDK, retriggering ad inspector.

nativeAdElement now measures each element with a GeometryReader inside a
coordinate space named on the NativeAdvertisement container, so its frame
is read directly rather than reconstructed by subtraction.

Also stop reassigning nativeAdView.nativeAd when only an element's position
changed (registration now runs only when the ad instance or the asset-view
set changes), update element constraints' constants in place instead of
deactivating and reinstalling them every frame, and skip reassigning
mediaContent when it hasn't changed so a playing video isn't restarted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A2rtVf6eKThpce2C9eKaB6

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors how SwiftUI native-ad element frames are captured and applied to the underlying GADNativeAdView, aiming to reduce layout/update overhead and prevent unnecessary SDK re-registration (including avoiding media playback restarts when the media content is unchanged).

Changes:

  • Switched element frame tracking from anchor-based preferences to direct GeometryReader measurement in a dedicated, type-safe coordinate space.
  • Optimized UIKit constraint updates by mutating existing constraint constants in place via ElementFittingConstraints rather than recreating/deactivating constraint arrays on every frame change.
  • Avoided redundant native ad asset re-registration when only element positions change, and guarded mediaContent reassignment with an identity check.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Sources/AdMobUI/Extensions/View+.swift Replaces anchorPreference with geometry-based frame reporting via ElementFramePreferenceKey.
Sources/AdMobUI/Components/UIViewRepresentable/_RepresentedUINativeAdView.swift Updates constraint handling, adds asset-view change detection to skip redundant registration, and avoids unnecessary mediaContent reassignment.
Sources/AdMobUI/Components/UIKit/ElementFittingConstraints.swift Introduces a role-addressable constraint container to enable constant mutation updates.
Sources/AdMobUI/Components/UIKit/_UINativeAdView.swift Updates stored constraint tracking to use ElementFittingConstraints.
Sources/AdMobUI/Components/TypedAnchorBoundsPreferenceKey.swift Removes anchor-preference-based tracking implementation.
Sources/AdMobUI/Components/TypedAnchor.swift Removes typed anchor wrapper used by the previous approach.
Sources/AdMobUI/Components/NativeAdvertisementCoordinateSpaceName.swift Adds a dedicated type for the ad container’s coordinate space name to avoid collisions.
Sources/AdMobUI/Components/ElementFramePreferenceKey.swift Adds a preference key for propagating measured element frames.
Sources/AdMobUI/Components/ElementFrame.swift Adds a shared ElementFrame model for measured element geometry.
Sources/AdMobUI/Components/AdMobNativeAd/NativeAdvertisement.swift Defines the coordinate space and consumes ElementFramePreferenceKey values to drive the overlay representable.
README.md Updates internal implementation description to match the new geometry/preference approach.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

3 participants