Description
On iOS, RNAppodealBannerView.m's bannerViewDidLoadAd: resets the banner's frame to origin (0, 0) once the ad loads, ignoring the container's actual bounds:
- (void)bannerViewDidLoadAd:(APDBannerView *)bannerView isPrecache:(BOOL)precache {
...
CGSize bannerSize = self.bannerView.adSize;
self.bannerView.frame = CGRectMake(0, 0, bannerSize.width, bannerSize.height);
...
}
This conflicts with layoutSubviews in the same file, which correctly centers the ad when the container is larger than the ad's natural size:
- (void)layoutSubviews {
[super layoutSubviews];
if (self.bannerView) {
CGSize bannerSize = self.bannerView.adSize;
if (CGRectGetWidth(self.bounds) > bannerSize.width || CGRectGetHeight(self.bounds) > bannerSize.height) {
CGRect bannerFrame = CGRectMake(
(self.bounds.size.width - bannerSize.width) / 2.0,
(self.bounds.size.height - bannerSize.height) / 2.0,
bannerSize.width,
bannerSize.height
);
self.bannerView.frame = bannerFrame;
} else {
self.bannerView.frame = self.bounds;
}
}
}
Because bannerViewDidLoadAd: runs after the ad loads and hardcodes the origin to (0, 0), the centering logic in layoutSubviews gets overridden the moment the ad actually has content, and the ad appears left-aligned instead of centered whenever the RN-side container is wider than the ad's natural size (e.g. a full-width container with a standard 320x50 banner).
This doesn't affect Android, since its RCTAppodealBannerView.kt/RNAppodealBannerViewManagerImpl.kt stretches the ad view to fill the full measured bounds of its container rather than relying on the ad's own natural size.
Reproduction
- Render
<AppodealBanner style={{ width: '100%' }} adSize="phone" /> inside a wider container (e.g. full device width) on iOS with the New Architecture (Fabric) enabled.
- Load a test ad (
Appodeal.setTesting(true)).
- Observe: once loaded, the ad renders flush against the left edge instead of centered.
Expected behavior
The ad should stay centered after loading, consistent with layoutSubviews' existing centering logic.
Suggested fix
In bannerViewDidLoadAd:, compute the frame the same way layoutSubviews does, instead of hardcoding (0, 0):
CGSize bannerSize = self.bannerView.adSize;
self.bannerView.frame = CGRectMake(
MAX(0, (self.bounds.size.width - bannerSize.width) / 2.0),
MAX(0, (self.bounds.size.height - bannerSize.height) / 2.0),
bannerSize.width,
bannerSize.height
);
[self invalidateIntrinsicContentSize];
[self setNeedsLayout];
Environment
- react-native-appodeal: 4.2.0
- react-native: 0.86.3
- New Architecture (Fabric): enabled
- Platform: iOS only (Android unaffected)
Description
On iOS,
RNAppodealBannerView.m'sbannerViewDidLoadAd:resets the banner's frame to origin(0, 0)once the ad loads, ignoring the container's actual bounds:This conflicts with
layoutSubviewsin the same file, which correctly centers the ad when the container is larger than the ad's natural size:Because
bannerViewDidLoadAd:runs after the ad loads and hardcodes the origin to(0, 0), the centering logic inlayoutSubviewsgets overridden the moment the ad actually has content, and the ad appears left-aligned instead of centered whenever the RN-side container is wider than the ad's natural size (e.g. a full-width container with a standard 320x50 banner).This doesn't affect Android, since its
RCTAppodealBannerView.kt/RNAppodealBannerViewManagerImpl.ktstretches the ad view to fill the full measured bounds of its container rather than relying on the ad's own natural size.Reproduction
<AppodealBanner style={{ width: '100%' }} adSize="phone" />inside a wider container (e.g. full device width) on iOS with the New Architecture (Fabric) enabled.Appodeal.setTesting(true)).Expected behavior
The ad should stay centered after loading, consistent with
layoutSubviews' existing centering logic.Suggested fix
In
bannerViewDidLoadAd:, compute the frame the same waylayoutSubviewsdoes, instead of hardcoding(0, 0):CGSize bannerSize = self.bannerView.adSize; self.bannerView.frame = CGRectMake( MAX(0, (self.bounds.size.width - bannerSize.width) / 2.0), MAX(0, (self.bounds.size.height - bannerSize.height) / 2.0), bannerSize.width, bannerSize.height ); [self invalidateIntrinsicContentSize]; [self setNeedsLayout];Environment