Anwendungen, die mehrere Fenster auf dem iPad unterstützen oder auf faltbaren Geräten wie dem iPhone Duo ausgeführt werden, können die Benutzeroberfläche in dynamischen Fenstergrößen und Bildschirmkonfigurationen anzeigen. Auf dem iPad können Nutzer mit mehreren gleichzeitigen Kopien der Benutzeroberfläche einer App interagieren und die Größe von Fenstern anpassen. Bei faltbaren Geräten bestimmt der Faltstatus des Geräts, welches Display aktiv ist. Im aufgeklappten Zustand wird das größere innere Display verwendet. Im zusammengeklappten Zustand wird das kleinere Außendisplay verwendet.
In diesem Leitfaden wird das Laden und Rendern von Anzeigen in Umgebungen mit Mehrfenstermodus und auf faltbaren Displays beschrieben.
Vorbereitung
Führen Sie zuerst die folgenden Schritte aus:
- Aktivieren Sie die Unterstützung für Szenen in Ihrem Projekt. Weitere Informationen findest du unter Von der App unterstützte Szenen angeben.
- Implementieren Sie mindestens ein Anzeigenformat:
- App-Start-Anzeige
Fensterszene in einer Anzeigenanfrage festlegen
Wenn Sie eine Anzeige erhalten möchten, die in ein bestimmtes Fenster oder eine bestimmte aktive Anzeige passt, weisen Sie das aktive UIWindowScene-Objekt der scene-Eigenschaft des GADRequest-Objekts zu. Google Mobile Ads SDK gibt eine Anzeige zurück, die für diese Szene optimiert ist. Fragen Sie in SwiftUI verbundene Szenen für die aktive Vordergrundfensterszene ab.
Im folgenden Beispiel wird die Fensteransicht konfiguriert, bei Erfolg eine Interstitial-Anzeige geladen und bei einem Fehler eine Fehlermeldung protokolliert:
Swift
func loadInterstitial() async {
let request = Request()
request.scene = view.window?.windowScene
do {
interstitial = try await InterstitialAd.load(
with: "ca-app-pub-3940256099942544/4411468910", request: request)
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
}
}
SwiftUI
func loadInterstitial() async {
let request = Request()
request.scene =
UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
do {
let _ = try await InterstitialAd.load(
with: "ca-app-pub-3940256099942544/4411468910", request: request)
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
}
}
Objective-C
- (void)loadInterstitial {
GADRequest *request = [GADRequest request];
request.scene = self.view.window.windowScene;
[GADInterstitialAd
loadWithAdUnitID:@"ca-app-pub-3940256099942544/4411468910"
request:request
completionHandler:^(GADInterstitialAd *ad, NSError *error) {
if (error) {
NSLog(@"Failed to load interstitial ad with error: %@", [error localizedDescription]);
return;
}
self.interstitial = ad;
}];
}
Im Testmodus schlagen Anzeigenanfragen mit dem folgenden Fehler fehl, wenn Ihre App mit mehreren Szenen eine Anzeige anfordert, ohne eine Szene zu übergeben:
<Google> Invalid Request. The GADRequest scene property should be set for
applications that support multi-scene. Treating the unset property as an error
while in test mode.
Im Produktionsmodus wird die Anzeigenanfrage ausgeführt, aber die Anzeige wird nicht präsentiert, wenn das Fenster kleiner als die Größe des Anzeigeninhalts ist:
<Google> Ad cannot be presented. The full screen ad content size exceeds the current window size.
Anzeigenanfrage erstellen
Beim Senden von Anzeigenanfragen ist für Anwendungen mit mehreren Szenen eine gültige Fensterszene erforderlich.
Wenn die Fensteransicht ausgefüllt ist, erstellen Sie Anzeigenanfragen mit der Methode viewDidAppear. Wir empfehlen diesen Prozess, da in der Methode viewDidLoad noch keine Ansicht zu einem Fenster hinzugefügt wurde.
Sie können die Methode viewDidAppear im Lebenszyklus einer App mehrmals aufrufen, müssen die Anzeigenanfrage aber in ein boolesches Flag einbinden, damit sie nur einmal ausgeführt wird.
Im folgenden Beispiel wird die Anzeigenanfrage in der Methode viewDidAppear initialisiert:
Swift
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !requestInitialized {
Task {
await loadInterstitial()
}
requestInitialized = true
}
}
Objective-C
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!_requestInitialized) {
[self loadInterstitial];
_requestInitialized = YES;
}
}
Größenänderung von Fenstern verarbeiten
Die Fensterabmessungen ändern sich, wenn Nutzer die Größe von Szenen auf dem iPad anpassen oder ein faltbares Gerät wie das iPhone Duo zusammen- und aufklappen. Wenn sich die Fenstergröße ändert, prüfen Sie, ob die geladenen Anzeigen in die aktualisierten Abmessungen passen, und laden Sie die Anzeigen gegebenenfalls neu.
Mit einer der folgenden Methoden können Sie prüfen, ob geladene Anzeigen den aktualisierten Abmessungen entsprechen:
viewWillTransitionToSize:withTransitionCoordinator:: Erkennt, wenn das Fenster des ViewControllers gedreht, in der Größe geändert oder zwischen Faltzuständen gewechselt wird.windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:: für Änderungen der Fensterszene.
Vollbildanzeigen
Mit der Methode canPresentFromRootViewController:error: können Sie prüfen, ob eine geladene Vollbildanzeige für die aktualisierte Fenstergröße oder den aktualisierten Faltstatus gültig bleibt. Wenn die Prüfung fehlschlägt, laden Sie eine Anzeige, die für die aktualisierte Szene geeignet ist.
Im folgenden Beispiel wird geprüft, ob eine Interstitial-Anzeige nach einer Größenänderung ausgeliefert werden kann. Falls erforderlich, wird die Anzeige neu geladen:
Swift
override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
guard let self else { return }
do {
try self.interstitial?.canPresent(from: self)
} catch {
Task {
await self.loadInterstitial()
}
}
}
}
Objective-C
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![self.interstitial canPresentFromRootViewController:self error:nil]) {
[self loadInterstitial];
}
}];
}
Banneranzeigen
Behandle Änderungen der Fenstergröße und des Faltstatus ähnlich wie die Gerätedrehung. Banneraufrufe auf die Property „safeAreaLayoutGuide“ beschränken. So werden Anzeigen nicht von Scharnieren, Aussparungen und Systemleisten verdeckt. Dabei wird auch die Größe des adaptiven Ankerbanners anhand der aktualisierten Breite des sicheren Bereichs neu berechnet.
Im folgenden Beispiel wird ein adaptives Ankerbanner mit der aktualisierten Fensterbreite während einer Größenänderung geladen:
Swift
override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
self?.loadBannerAd()
}
}
@MainActor
func loadBannerAd() {
let frame = view.frame.inset(by: view.safeAreaInsets)
let viewWidth = frame.size.width
bannerView.adSize = largeAnchoredAdaptiveBanner(width: viewWidth)
let request = Request()
request.scene = view.window?.windowScene
bannerView.load(request)
}
SwiftUI
struct MultiSceneBannerView: View {
var body: some View {
GeometryReader { geometry in
let adSize = largeAnchoredAdaptiveBanner(width: geometry.size.width)
MultiSceneBannerViewContainer(adSize: adSize)
.frame(width: adSize.size.width, height: adSize.size.height)
}
}
}
private struct MultiSceneBannerViewContainer: UIViewRepresentable {
let adSize: AdSize
func makeUIView(context: Context) -> BannerView {
let bannerView = BannerView(adSize: adSize)
let request = Request()
request.scene =
UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
bannerView.load(request)
return bannerView
}
func updateUIView(_ uiView: BannerView, context: Context) {
if uiView.adSize.size != adSize.size {
uiView.adSize = adSize
let request = Request()
request.scene = uiView.window?.windowScene
uiView.load(request)
}
}
}
Objective-C
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self loadBannerAd];
}];
}
- (void)loadBannerAd {
dispatch_async(dispatch_get_main_queue(), ^{
CGRect frame = UIEdgeInsetsInsetRect(self.view.frame, self.view.safeAreaInsets);
CGFloat viewWidth = frame.size.width;
self.bannerView.adSize = GADLargeAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth);
GADRequest *request = [GADRequest request];
request.scene = self.view.window.windowScene;
[self.bannerView loadRequest:request];
});
}
Native Anzeigen
Sie bestimmen das Layout nativer Anzeigen. Im Gegensatz zu Bannern oder Vollbildanzeigen müssen native Anzeigen nicht neu geladen werden, wenn die Fenstergröße geändert wird. Verwenden Sie für die native Anzeigenansicht Standard-Auto-Layout-Einschränkungen oder SwiftUI-Layouts, um sie an Größenänderungen anzupassen.