<br />

[Banner ads](https://support.google.com/admanager/answer/10017110) are rectangle ads that occupy a portion of an app's layout. Anchored adaptive banners are always on-screen, anchored to the top or bottom of the screen with a maximum height of 20% of the screen size with a 150px max height. To optimize ad size for each device, use adaptive banners.

<br />

This guide covers loading an anchored adaptive banner ad into an iOS app.

## Prerequisites

Before you continue, [set up Google Mobile Ads SDK](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/quick-start.md.txt).

## Always test with test ads

When building and testing your apps, make sure you use test ads rather than
live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for iOS
banners:

`/21775744923/example/adaptive-banner`

It's been specially configured to return test ads for every request, and you're
free to use it in your own apps while coding, testing, and debugging. Just make
sure you replace it with your own ad unit ID before publishing your app.

For more information about how Google Mobile Ads SDK test ads work, see [Test
Ads](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads).

## Create a GAMBannerView

Banner ads are displayed in [`GAMBannerView`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GAMBannerView.md.txt)
objects, so the first step toward integrating banner ads is to include a `GAMBannerView`
in your view hierarchy. This is typically done either programmatically or
through Interface Builder.

### Programmatically

A `GAMBannerView` can also be instantiated directly.
The following example creates a `GAMBannerView`:

### Swift

```swift
// Initialize the banner view.
bannerView = AdManagerBannerView()
bannerView.delegate = self

bannerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(bannerView)

// This example doesn't give width or height constraints, as the ad size gives the banner an
// intrinsic content size to size the view.
NSLayoutConstraint.activate([
  // Align the banner's bottom edge with the safe area's bottom edge
  bannerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
  // Center the banner horizontally in the view
  bannerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
])
```

### SwiftUI

To use a `AdManagerBannerView`, create a [`UIViewRepresentable`](https://developer.apple.com/documentation/swiftui/uiviewrepresentable):

```swift
private struct BannerViewContainer: UIViewRepresentable {
  typealias UIViewType = BannerView
  let adSize: AdSize

  init(_ adSize: AdSize) {
    self.adSize = adSize
  }

  func makeUIView(context: Context) -> BannerView {
    let banner = BannerView(adSize: adSize)
    banner.adUnitID = "ca-app-pub-3940256099942544/2435281174"
    banner.load(Request())
    banner.delegate = context.coordinator
    return banner
  }

  func updateUIView(_ uiView: BannerView, context: Context) {}

  func makeCoordinator() -> BannerCoordinator {
    return BannerCoordinator(self)
  }
```

Add your `UIViewRepresentable` to the view hierarchy, specifying `height` and
`width` values:

```swift
var body: some View {
  Spacer()
  // Request an anchored adaptive banner with a width of 375.
  let adSize = largeAnchoredAdaptiveBanner(width: 375)
  BannerViewContainer(adSize)
    .frame(width: adSize.size.width, height: adSize.size.height)
}
```

### Objective-C

```objective-c
// Initialize the banner view.
GAMBannerView *bannerView = [[GAMBannerView alloc] init];
bannerView.delegate = self;
UIView *view = self.view;

bannerView.translatesAutoresizingMaskIntoConstraints = NO;
[view addSubview:bannerView];

// This example doesn't give width or height constraints, as the ad size gives the banner an
// intrinsic content size to size the view.
[NSLayoutConstraint activateConstraints:@[
  // Align the banner's bottom edge with the safe area's bottom edge
  [bannerView.bottomAnchor
      constraintEqualToAnchor:view.safeAreaLayoutGuide.bottomAnchor],
  // Center the banner horizontally in the view
  [bannerView.centerXAnchor constraintEqualToAnchor:view.centerXAnchor],
]];

self.bannerView = bannerView;
```

### Interface Builder

You can add a `GAMBannerView` to a storyboard or xib file. When using this
method, be sure to only add position constraints on the banner. For example,
when displaying an adaptive banner at the bottom of the screen, set the bottom
of the banner view equal to the top of the Bottom Layout Guide, and set the
[`centerX`](https://developer.apple.com/documentation/uikit/nslayoutconstraint/attribute/centerx/)
constraint equal to the `centerX` of the superview.

## Set the ad size

Large adaptive banners provide a larger format designed for non-scrolling
layouts. Compared to standard anchored adaptive banners, these banners
allow a taller maximum height (up to 20% of screen height, between 50 and
150 points). This increased space is optimized for video content.

The following example gets a large anchored adaptive banner size:

### Swift

```swift
// Request a large anchored adaptive banner with a width of 375.
bannerView.adSize = largeAnchoredAdaptiveBanner(width: 375)
```

### Objective-C

```objective-c
// Request a large anchored adaptive banner with a width of 375.
self.bannerView.adSize = GADLargeAnchoredAdaptiveBannerAdSizeWithWidth(375);
```

Set an ad size smaller than or equal to the device screen size.
To determine the maximum screen size on iOS 26 and later, use the
[`UIWindowScene.effectiveGeometry.coordinateSpace`](https://developer.apple.com/documentation/uikit/uiwindowscene/geometry/coordinatespace)
property. On iOS 18 and earlier, use the
[`UIWindowScene.coordinateSpace`](https://developer.apple.com/documentation/uikit/uiwindowscene/coordinatespace)
property.
For details about size constraints, see
[Troubleshoot unfilled impressions in Ad Manager](https://support.google.com/admanager/answer/1739296).


## Load an ad

Once the `GAMBannerView` is in place and its properties, such as `adUnitID`,
are configured, it's time to load an ad. This is done by calling `loadRequest:`
on a [`GAMRequest`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GAMRequest.md.txt)
object:

### Swift

```swift
func loadBannerAd(bannerView: AdManagerBannerView) {
  // Request a large anchored adaptive banner with a width of 375.
  bannerView.adSize = largeAnchoredAdaptiveBanner(width: 375)
  bannerView.load(AdManagerRequest())
}
```

### SwiftUI

```swift
banner.adUnitID = "ca-app-pub-3940256099942544/2435281174"
banner.load(Request())
```

### Objective-C

```objective-c
// Request a large anchored adaptive banner with a width of 375.
self.bannerView.adSize = GADLargeAnchoredAdaptiveBannerAdSizeWithWidth(375);

[self.bannerView loadRequest:[GAMRequest request]];
```

`GAMRequest` objects represent a single ad request, and contain properties
for things like targeting information.


> [!TIP]
> **Tip:** You can use ad load calls to build up a cache of preloaded ads before you intend to show them, so that ads can be shown with zero latency when needed. Because ads expire after an hour, you should clear this cache and reload with new ads every hour.

<br />

## Refresh an ad

If you configured your ad unit to refresh, you don't need to request another ad
when the ad fails to load. Google Mobile Ads SDK respects any refresh rate
you specified in the Ad Manager UI. If you haven't enabled
refresh, issue a new request. For more details on ad unit refresh, such as
setting a refresh rate, see

[Refresh rate for ads in mobile apps](https://support.google.com/admanager/answer/6022114).

> [!NOTE]
> **Note:** When setting a refresh rate in the Ad Manager UI, the automatic refresh occurs only if the banner is visible on screen.

## Handle orientation changes

When your app's screen orientation changes, such as from
[`portrait`](https://developer.apple.com/documentation/uikit/uiinterfaceorientation/portrait)
mode to landscape, the available width for the banner often changes as well. To
make sure you display an appropriately sized ad for the new layout, request a
new banner. If your banner width is static, or if your layout constraints can
handle the resize, skip this step.

### Swift

```swift
override func viewWillTransition(
  to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
  coordinator.animate(alongsideTransition: { _ in
    // Load a new ad for the new orientation.
  })
}
```

### Objective-C

```objective-c
- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
  [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    // Load a new ad for the new orientation.
  } completion:nil];
}
```

## Ad events

Through the use of `GADBannerViewDelegate`, you can listen for lifecycle events,
such as when an ad is closed or the user leaves the app.

### Register for banner events

To register for banner ad events, set the `delegate` property on
`GAMBannerView` to an object that implements the
`GADBannerViewDelegate` protocol. Generally, the class that implements banner
ads also acts as the delegate class, in which case, the `delegate` property can
be set to `self`.

### Swift

```swift
bannerView.delegate = self
```

### SwiftUI

```swift
banner.delegate = context.coordinator
```

### Objective-C

```objective-c
bannerView.delegate = self;
```

### Implement banner events

Each of the methods in `GADBannerViewDelegate` is marked as optional, so you
only need to implement the methods you want. This example implements each method
and logs a message to the console:

### Swift

```swift
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
  print("Banner ad loaded.")
}

func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
  print("Banner ad failed to load: \(error.localizedDescription)")
}

func bannerViewDidRecordImpression(_ bannerView: BannerView) {
  print("Banner ad recorded an impression.")
}

func bannerViewDidRecordClick(_ bannerView: BannerView) {
  print("Banner ad recorded a click.")
}

func bannerViewWillPresentScreen(_ bannerView: BannerView) {
  print("Banner ad will present screen.")
}

func bannerViewWillDismissScreen(_ bannerView: BannerView) {
  print("Banner ad will dismiss screen.")
}

func bannerViewDidDismissScreen(_ bannerView: BannerView) {
  print("Banner ad did dismiss screen.")
}

```

### Objective-C

```objective-c
- (void)bannerViewDidReceiveAd:(GAMBannerView *)bannerView {
  NSLog(@"bannerViewDidReceiveAd");
}

- (void)bannerView:(GAMBannerView *)bannerView didFailToReceiveAdWithError:(NSError *)error {
  NSLog(@"bannerView:didFailToReceiveAdWithError: %@", error.localizedDescription);
}

- (void)bannerViewDidRecordImpression:(GAMBannerView *)bannerView {
  NSLog(@"bannerViewDidRecordImpression");
}

- (void)bannerViewWillPresentScreen:(GAMBannerView *)bannerView {
  NSLog(@"bannerViewWillPresentScreen");
}

- (void)bannerViewWillDismissScreen:(GAMBannerView *)bannerView {
  NSLog(@"bannerViewWillDismissScreen");
}

- (void)bannerViewDidDismissScreen:(GAMBannerView *)bannerView {
  NSLog(@"bannerViewDidDismissScreen");
}

```

See the Ad Delegate example for an implementation of banner delegate methods in
the iOS API Demo app.

[Swift](https://github.com/googleads/googleads-mobile-ios-examples/blob/main/Swift/advanced/APIDemo/APIDemo/AdMobAdDelegateViewController.swift)
[Objective-C](https://github.com/googleads/googleads-mobile-ios-examples/blob/main/Objective-C/advanced/APIDemo/APIDemo/AdMobAdDelegateViewController.m)

### Use cases

Here are some example use cases for these ad event methods.

#### Add a banner to the view hierarchy once an ad is received

You may want to delay in adding a `GAMBannerView` to
the view hierarchy until after an ad is received. You can do this by listening
for the `bannerViewDidReceiveAd:` event:

### Swift

```swift
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
  // Add banner to view and add constraints.
  addBannerViewToView(bannerView)
}
```

### Objective-C

```objective-c
- (void)bannerViewDidReceiveAd:(GAMBannerView *)bannerView {
  // Add bannerView to view and add constraints as above.
  [self addBannerViewToView:self.bannerView];
}
```

#### Animate a banner ad

You can also use the `bannerViewDidReceiveAd:` event to animate a banner ad once
it's returned, as shown in the following example:

### Swift

```swift
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
  bannerView.alpha = 0
  UIView.animate(withDuration: 1, animations: {
    bannerView.alpha = 1
  })
}
```

### Objective-C

```objective-c
- (void)bannerViewDidReceiveAd:(GAMBannerView *)bannerView {
  bannerView.alpha = 0;
  [UIView animateWithDuration:1.0 animations:^{
    bannerView.alpha = 1;
  }];
}
```

#### Pause and resume the app

The `GADBannerViewDelegate` protocol has methods to notify you of events, such
as when a click causes an overlay to be presented or dismissed. If you want to
trace whether these events were due to ads, register for these
`GADBannerViewDelegate` methods.

To catch all types of overlay presentations or external browser invocations, not
just those that come from ad clicks, your app is better off listening for the
equivalent methods on `UIViewController` or `UIApplication`. Here is a table
showing the equivalent iOS methods that are invoked at the same time as
`GADBannerViewDelegate` methods:

| GADBannerViewDelegate method | iOS method |
|---|---|
| `bannerViewWillPresentScreen:` | UIViewController's `viewWillDisappear:` |
| `bannerViewWillDismissScreen:` | UIViewController's `viewWillAppear:` |
| `bannerViewDidDismissScreen:` | UIViewController's `viewDidAppear:` |

## Manual impression counting

> [!IMPORTANT]
> **Important:** Manual impression counting is compatible only with direct-sold and house campaigns (that is, creatives trafficked directly in Ad Manager). It shouldn't be used for backfill or third-party networks ads. For more details, see [this help center article](https://support.google.com/admanager/answer/2521337).

You can manually send impression pings to Ad Manager if you have special
conditions for when an impression should be recorded. This can be done by first
enabling a `GAMBannerView` for manual impressions prior to loading an ad:

### Swift

```swift
bannerView.enableManualImpressions = true
```

### Objective-C

```objective-c
self.bannerView.enableManualImpressions = YES;
```

When you determine that an ad has been successfully returned and is on screen,
you can manually fire an impression:

### Swift

```swift
bannerView.recordImpression()
```

### Objective-C

```objective-c
[self.bannerView recordImpression];
```

> [!NOTE]
> **Note:** Impressions are automatically fired when the `bannerViewDidReceiveAd:` callback is invoked. You should only consider using this feature if you want to record impressions at a different point in time.

## App events

You can listen for Ad Manager-specific app events using `GADAppEventDelegate`.
These events may occur at any time during the ad's lifecycle, even before the
`GADBannerViewDelegate` object's `bannerViewDidReceiveAd:` is called.

To register for app events, set the delegate property on `GAMBannerView` to an
object that implements the `GADAppEventDelegate` protocol. Generally, the class
that implements banner ads also acts as the delegate class, in which case, the
delegate property can be set to `self`.

### Swift

```swift
// Set this property before making the request for an ad.
bannerView.appEventDelegate = self
```

### Objective-C

```objective-c
// Set this property before making the request for an ad.
self.bannerView.appEventDelegate = self;
```

Here is an example showing how to change the background color of your app by
specifying the color from an app event:

### Swift

```swift
func bannerView(
  _ banner: AdManagerBannerView, didReceiveAppEvent name: String, withInfo info: String?
) {
  if name == "color" {
    if info == "green" {
      // Set background color to green.
      view.backgroundColor = UIColor.green
    } else if info == "blue" {
      // Set background color to blue.
      view.backgroundColor = UIColor.blue
    } else {
      // Set background color to black.
      view.backgroundColor = UIColor.black
    }
  }
}
```

### Objective-C

```objective-c
- (void)bannerView:(GAMBannerView *)banner
    didReceiveAppEvent:(NSString *)name
              withInfo:(NSString *)info {
  if ([name isEqual:@"color"]) {
    if ([info isEqual:@"green"]) {
      // Set background color to green.
      self.view.backgroundColor = [UIColor greenColor];
    } else if ([info isEqual:@"blue"]) {
      // Set background color to blue.
      self.view.backgroundColor = [UIColor blueColor];
    } else {
      // Set background color to black.
      self.view.backgroundColor = [UIColor blackColor];
    }
  }
}
```

And, here is the corresponding creative that sends color app event messages to
`appEventDelegate`:

    <html>
    <head>
      <script src="//www.gstatic.com/afma/api/v1/google_mobile_app_ads.js"></script>
      <script>
        document.addEventListener("DOMContentLoaded", function() {
          // Send a color=green event when ad loads.
          admob.events.dispatchAppEvent("color", "green");

          document.getElementById("ad").addEventListener("click", function() {
            // Send a color=blue event when ad is clicked.
            admob.events.dispatchAppEvent("color", "blue");
          });
        });
      </script>
      <style>
        #ad {
          width: 320px;
          height: 50px;
          top: 0px;
          left: 0px;
          font-size: 24pt;
          font-weight: bold;
          position: absolute;
          background: black;
          color: white;
          text-align: center;
        }
      </style>
    </head>
    <body>
      <div id="ad">Carpe diem!</div>
    </body>
    </html>

See the Ad Manager App Events example for an implementation of app events in the
iOS API Demo app.

[Swift](https://github.com/googleads/googleads-mobile-ios-examples/blob/main/Swift/advanced/APIDemo/APIDemo/AdManagerAppEventsViewController.swift)
[Objective-C](https://github.com/googleads/googleads-mobile-ios-examples/blob/main/Objective-C/advanced/APIDemo/APIDemo/GAMAppEventsViewController.m)

## Additional resources

### Examples on GitHub

- Anchored adaptive banner ads example: [Swift](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Swift/admanager/AdManagerBannerExample) \| [SwiftUI](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Swift/advanced/SwiftUIDemo/SwiftUIDemo/Banner) \| [Objective-C](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Objective-C/admanager/AdManagerBannerExample)

<!-- -->

- Advanced features demo: [Swift](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Swift/advanced/APIDemo) \| [Objective-C](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Objective-C/advanced/APIDemo)

## Next steps

### Collapsible banners

Collapsible banner ads are banner ads that are initially presented as a larger
overlay, with a button to collapse the ad to a smaller size. Consider using it
to further optimize your performance. See [collapsible banner ads](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/banner/collapsible.md.txt) for more details.

### Inline adaptive banners

Inline adaptive banners are larger, taller banners compared to anchored adaptive
banners. They are of variable height, and can be as tall as the device screen.
Inline adaptive banners are recommended over anchored adaptive banner ads for
apps that place banner ads in scrollable content. See [inline adaptive
banners](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/banner/inline-adaptive) for more
details.

### Explore other topics

- [User privacy](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/privacy.md.txt)