Working with Banner Views

Banner views use a delegate to communicate with your app. Your app implements a banner view delegate to handle common events in a banner view’s lifecycle. Your app must:

A typical pattern is to implement these methods in your custom view controller, but you may implement them on another object if you prefer.

If your app supports orientation changes, your view controller must also change the banner view’s size when the orientation of the device changes.

Responding to Banner Events

Most banner view delegates implement all of the following behaviors:

Responding to a Touch in the Banner View

Before the banner view triggers an advertising action, it calls the delegate’s bannerViewActionShouldBegin:willLeaveApplication: method. Your delegate method performs two tasks:

  • It decides whether to allow the action to be triggered.

  • If the action will cover your app’s user interface, this method pauses any activities that require user interaction.

Your delegate should return YES from this method if it wants to allow the action to be triggered. It can prevent the action from being triggered by returning NO. Your app should always allow actions to be triggered unless it cannot safely do so.

  • If the willLeave parameter is YES, then your app is going to be moved to the background after it returns from this delegate method. This process is described in “Defining a Document-Based Data Model” in iOS App Programming Guide.

  • If the willLeave parameter is NO, iAd covers the app’s user interface after it returns from this delegate method. Your app should disable sounds, animations or other activities that require user interaction before returning. For example, a real-time game should pause gameplay, then return YES to allow the action to be triggered.

“Creating a Banner View” shows the typical pattern for how your app should implement this delegate method:

Listing 2-1  Allowing an action to be triggered

- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
    NSLog(@"Banner view is beginning an ad action");
    BOOL shouldExecuteAction = [self allowActionToRun]; // your app implements this method
    if (!willLeave && shouldExecuteAction)
    {
        // insert code here to suspend any services that might conflict with the advertisement
    }
    return shouldExecuteAction;
}

If the banner view covered your app’s user interface, it calls the delegate’s bannerViewActionDidFinish: method after the interface is restored. Your implementation of this method should restore any services paused by your app.

On iOS 4.2 and earlier, your app should not delete the banner view object while the user is interacting with the advertisement. Only delete the banner view after the banner view delegate’s bannerViewActionDidFinish: method is called.

Responding When an Advertisement Loads

The iAd framework makes it easy to adopt an asynchronous model and only display an ad when one is available. Your app should never display an empty banner view. Instead, it should show the banner when an advertisement is available and hide the banner when it has nothing to show.

When a banner view has a new advertisement to display, it calls the delegate's bannerViewDidLoadAd: method. This method is called even if the banner view is not currently part of the view hierarchy. Your app can use this method to add the view to a view hierarchy or to move the banner view on screen. “Banner View Sizes” uses a property to track whether the banner view is visible. If the banner is not visible and a new advertisement is loaded, the method animates the view onto the screen.

Listing 2-2  Animating in the banner view after a new advertisement is loaded

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    if (!self.bannerIsVisible)
    {
        [UIView beginAnimations:@"animateAdBannerOn" context:NULL];
// Assumes the banner view is just off the bottom of the screen.
        banner.frame = CGRectOffset(banner.frame, 0, -banner.frame.size.height);
        [UIView commitAnimations];
        self.bannerIsVisible = YES;
    }
}

Error Handling

If an error occurs, the banner view calls the delegate’s bannerView:didFailToReceiveAdWithError: method. When this happens, your app must hide the banner view. Listing 2-3 shows one way you might implement this. It uses the same property as Listing 2-2 to keep track of whether the banner is visible. If the banner is visible and an error occurs, it moves the banner off the screen.

Listing 2-3  Removing a banner view when advertisements are not available

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
   if (self.bannerIsVisible)
    {
        [UIView beginAnimations:@"animateAdBannerOff" context:NULL];
// Assumes the banner view is placed at the bottom of the screen.
        banner.frame = CGRectOffset(banner.frame, 0, banner.frame.size.height);
        [UIView commitAnimations];
        self.bannerIsVisible = NO;
    }
}

Even after an error is sent to your delegate, the banner view continues to try to download new advertisements. Thus, implementing both of these delegate methods allows your app to display the banner only when advertisements are loaded.

Canceling an Advertising Action

When the banner view covers your app’s user interface to perform its action, your app continues to receive events. Your app can read the bannerViewActionInProgress property of the banner view to determine whether a banner action is executing. Your app should scale back its activities and avoid actions that require interaction with the user.

If an event occurs that requires the user’s attention, you can invoke the banner view’s cancelBannerViewAction method to cancel the advertising action. The action ends, and the banner view calls the delegate’s bannerViewActionDidFinish: method.

Changing the Banner Size Dynamically

Apps that intend to resize the banner view after creation should configure the requiredContentSizeIdentifiers property with the set of all possible sizes the view can take in your app. The most common reason to support multiple sizes in your app is to support orientation changes. If your app changes its interface in response to an orientation change, it should resize the banner view to fit the new orientation.

Listing 2-4 shows how a view controller could configure the banner view to download advertisements that have both portrait and landscape images:

Listing 2-4  Configuring a banner view to handle landscape and portrait orientations

self.bannerView.requiredContentSizeIdentifiers = [NSSet setWithObjects: ADBannerContentSizeIdentifierPortrait, ADBannerContentSizeIdentifierLandscape, nil];

When an orientation change occurs, your view controller’s willRotateToInterfaceOrientation:duration: method changes the banner size.

Listing 2-5  Responding to an orientation change

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
        self.bannerView.currentContentSizeIdentifier =
            ADBannerContentSizeIdentifierLandscape;
    else
        self.bannerView.currentContentSizeIdentifier =
            ADBannerContentSizeIdentifierPortrait;
}

When your app configures the requiredContentSizeIdentifiers property with more than one banner size, the iAd service only downloads advertisements that provide images for all of the specified sizes. This allows the banner view to seamlessly change the displayed advertisement when your app changes the size of the view. As this restricts the ads available to the banner view, you should only configure the requiredContentSizeIdentifiers property with sizes that are actually used by your app.

Banner View Best Practices

When designing your app, keep the following principles in mind: