Search code examples
iosobjective-ciad

How to correctly place an iAd Banner over a Tab Controller?


I am trying to add an iAd banner on top of a TabBar, which is 50pts above the bottom of the screen, but for some reason, the Banner moves up, 50pts, across the screen, every time, after it refreshes.

I'm initializing it in the tabBarViewController this way:

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    if (!_bannerIsVisible)
    {
        // If banner isn't part of view hierarchy, add it
        if (_adBanner.superview == nil)
        {
            [self.view addSubview:_adBanner];
        }

        [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];

        _bannerIsVisible = YES;
    }
}

and I'm placing it like this:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    _adBanner = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, 320, 50)];

    _adBanner.delegate = self;
}

why is it that this happens?


Solution

  • The code you are using is quite an old way of implementing an ADBannerView. The reason your ADBannerView is moving vertically across the screen is because of this line banner.frame = CGRectOffset(banner.frame, 0, -banner.frame.size.height);. It is offsetting your ADBannerView's y position by 50pts each time it receives a new ad from the iAd network. I'm assuming that in your bannerView:didFailToReceiveAdWithError: you are not setting your _bannerIsVisible properly, should be _bannerIsVisible = NO from what I can gather. Also, you should be creating your ADBannerView once in your viewDidLoad, not in your viewDidAppear as this will most likely be called more than once in your app session.

    Alternatively, you could set your ADBannerView's position based on the position of your UITabBar. Then, when you do not receive an ad from iAd you could either animate it off the view or hide the ADBannerView completely. You should be setting your ADBannerView's dimensions based on the size of the view it is on also. With all the different screen sizes available now, and more to come in the future, setting things up in this way will assure your ADBannerView continues to work with minimal maintenance when new devices are introduced.

    Here's an example of what I am suggesting. I've commented out most of it. Let me know if you need any further clarification.

    #import "ViewController.h"
    @import iAd; // Import iAd
    
    @interface ViewController () <ADBannerViewDelegate> // Include delegate
    // Outlet to a UITabBar I created in Interface Builder
    @property (weak, nonatomic) IBOutlet UITabBar *myTabBar;
    @end
    
    @implementation ViewController {
        ADBannerView *iAdBannerView;
    }
    
    -(void)viewDidLoad {
        [super viewDidLoad];
    
        iAdBannerView = [[ADBannerView alloc] initWithFrame:CGRectZero];
        iAdBannerView.frame = CGRectMake(0, // x = 0
                                         self.view.frame.size.height - self.myTabBar.frame.size.height - iAdBannerView.frame.size.height,
                                         // y = get the height of our view, subtract the height of our UITabBar, subtract the height of our ADBannerView
                                         self.view.frame.size.width, // width = stretch our ADBannerView across the width of our view
                                         iAdBannerView.frame.size.height); // height = height of our ADBannerView
        iAdBannerView.alpha = 0.0; // Hide our ADBannerView initially because it takes a second to receive an ad
        iAdBannerView.delegate = self; // Set its delegate
        [self.view addSubview:iAdBannerView]; // Add it to our view
    }
    
    -(void)bannerViewDidLoadAd:(ADBannerView *)banner {
        NSLog(@"bannerViewDidLoadAd");
    
        // Fade in our ADBannerView
        [ADBannerView animateWithDuration:0.2
                                delay:0
                              options:0
                           animations:^{
                               iAdBannerView.alpha = 1.0;
                           }
                           completion:^(BOOL finished) {
                               if (finished) {
                                   // If you wanted to do anything once the animation finishes
                               }
                           }];
    }
    
    -(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
        NSLog(@"didFailToReceiveAdWithError: %@", error);
    
        // Fade out our ADBannerView
        [ADBannerView animateWithDuration:0.2
                                delay:0
                              options:0
                           animations:^{
                               iAdBannerView.alpha = 0.0;
                           }
                           completion:^(BOOL finished) {
                               if (finished) {
                               }
                           }];
    }
    

    You should familiarize yourself with these Apple Docs also: ADBannerViewDelegate, CGRectOffset, viewDidAppear, frame.