1

I have a tableView with a list of ViewControllers. At the bottom of this tableview is an ad via iAd. When you visit any of these VCs, then hit "back" on the navigationController, the iAd is just as you left it--except for one of the viewcontrollers. After visiting this one, the ad is as you left it for a split second, then goes white for about ten seconds, then finally--sometimes--reloads another ad. I'm not sure what about pushing this certain VC causes the ad to fail when you go back to it. I'm thinking maybe something UI-related on the background thread, or something thread-related, but I'm not sure at all. Here is the VC's code that, after hitting "back" on the navControl, causes the tableView's ad to go white (this VC, another tableView, has it's own iAd and iAd delegate methods):

#import "RosterTableTableViewController.h"
#import "RosterListing.h"
#import "RosterListingCellTableViewCell.h"
#import "PlayerDetailViewController.h"
#import <iAd/iAd.h>
#import "RosterListingModel.h"

@interface RosterTableTableViewController () <ADBannerViewDelegate>
{
    RosterListingModel *_homeModel;
    BOOL _bannerIsVisible;
    ADBannerView *_adBanner;
}

@property (nonatomic, strong) NSMutableArray *rosters;
@property NSCache *imageCache;
@property UIActivityIndicatorView *spinner;

@end

@implementation RosterTableTableViewController

-(void)itemsDownloaded:(NSArray *)items
{
    // This delegate method will get called when the items are finished downloading

    // Set the downloaded items to the array
    _rosters = [items copy];

    [_spinner stopAnimating];

    // Reload the table view
    [self.tableView reloadData];
}

- (instancetype)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Create new HomeModel object and assign it to _homeModel variable
        _homeModel = [[RosterListingModel alloc] init];

        self.navigationItem.title = @"Roster";
        self.imageCache = [[NSCache alloc] init];
        self.rosters = [[NSMutableArray alloc] init];

        // Set this view controller object as the delegate for the home model object
        _homeModel.delegate = self;

        // Call the download items method of the home model object
        [_homeModel downloadItems];

    }
    return self;
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    NSLog(@"Failed to retrieve ad");

    if (_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];

        _bannerIsVisible = NO;
    }
}

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear: animated];
    [UIView setAnimationsEnabled:YES];
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"RosterDetail" bundle:nil];
    PlayerDetailViewController *vc = [sb instantiateViewControllerWithIdentifier:@"PlayerDetailViewController"];


    // Give the PlayerViewController its key
    RosterListing *rl = [self.rosters objectAtIndex:indexPath.row];
    vc.playerNumberKey = rl.playerNumber;
    vc.playerNameKey = rl.playerName;
    vc.playerImage = rl.image;

    // Present vc
    vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    //[self.navigationController pushViewController:vc animated:YES];
    [UIView beginAnimations:@"animation" context:nil];
    [self.navigationController pushViewController: vc animated:NO];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
    [UIView setAnimationDuration:0.75];
    [UIView commitAnimations];

}

- (void)viewDidLoad {
    [super viewDidLoad];



    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
                                        initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenWidth = screenRect.size.width;
    CGFloat screenHeight = screenRect.size.height;

    spinner.center = CGPointMake(screenWidth/2.0, screenHeight/5.0);
    spinner.hidesWhenStopped = YES;
    spinner.color = [UIColor blackColor];
    [self.view addSubview:spinner];
    [spinner startAnimating];
    _spinner = spinner;

    // Load the Cell NIB file
    UINib *nib = [UINib nibWithNibName:@"RosterListingCellTableViewCell" bundle:nil];

    // Register this NIB, which contains the cell
    [self.tableView registerNib:nib forCellReuseIdentifier:@"RosterCell"];

    // Background
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ticketBackground"]];
    imageView.contentMode = UIViewContentModeScaleAspectFill;

    self.tableView.backgroundView = imageView;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 74;
}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return self.rosters.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Get a new or recycled cell
    RosterListingCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RosterCell" forIndexPath:indexPath];

    RosterListing *thisRosterListing = [self.rosters objectAtIndex:indexPath.row];
    cell.playerNumberLabel.text = [NSString stringWithFormat:@"#%@",thisRosterListing.playerNumber];
    cell.playerNameLabel.text = thisRosterListing.playerName;


    cell.imageView.image = [UIImage imageNamed:@"omaha"];


    cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
    cell.imageView.clipsToBounds = YES;

    UIImage *playerImage = [self.imageCache objectForKey:thisRosterListing.playerImageURL];
    cell.imageView.image = playerImage;
    if (playerImage == nil) {

        NSURLSessionConfiguration *sessionConfig =
        [NSURLSessionConfiguration defaultSessionConfiguration];

        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
        thisRosterListing.playerImageURL = [thisRosterListing.playerImageURL stringByReplacingOccurrencesOfString:@"small" withString:@"medium"];
        NSURLSessionDataTask *imageData = [session dataTaskWithURL:[NSURL URLWithString: thisRosterListing.playerImageURL]
                                                completionHandler:^(NSData *data,
                                                                    NSURLResponse *response,
                                                                    NSError *error) {
                                                    // handle NSData
                                                    UIImage *image = [UIImage imageWithData:data];
                                                    thisRosterListing.image = image;
                                                    [self.imageCache setObject:image forKey:thisRosterListing.playerImageURL];

                                                    dispatch_async(dispatch_get_main_queue(), ^{
                                                        cell.imageView.image = image;
                                                        [self.tableView reloadData];
                                                    });
                                                }];
        [imageData resume];
    }


    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    imageView.image = [UIImage imageNamed:@"indicator"];
    cell.accessoryView = imageView;
    cell.backgroundColor = [UIColor clearColor];

    // set selection color
    UIView *myBackView = [[UIView alloc] initWithFrame:cell.frame];
    myBackView.backgroundColor = [UIColor clearColor];
    cell.selectedBackgroundView = myBackView;

    return cell;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 65)];
    view.backgroundColor = [UIColor clearColor];

    if (_adBanner == nil)
    {
        _adBanner = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    }

    _adBanner.delegate = self;
    _adBanner.backgroundColor = [UIColor clearColor];
    [view addSubview:_adBanner];

    return view;

}

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 65;
}

@end
Jameson
  • 4,198
  • 4
  • 17
  • 31
  • Where are the rest of your `ADBannerView` [delegate methods](https://developer.apple.com/library/ios/documentation/UserExperience/Reference/ADBannerViewDelegate_Ref/index.html#//apple_ref/occ/intf/ADBannerViewDelegate)? This `_adBanner.backgroundColor = [UIColor clearColor];` is not how you should be hiding your `ADBannerView`. You either need to create a [Shared Banner](http://stackoverflow.com/a/28639200/2108547) and/or [correctly implement your banner](http://stackoverflow.com/a/28708377/2108547). – Daniel Storm Jun 08 '15 at 12:44
  • The "correctly implement your banner" link does not require a shared banner? It's more or less what I was doing, no? Now I have to separate ads (iAd and a google ad) and if iAd loads, the google ad sets its alpha to 0, and if the iAd doesn't load it sets it alpha to 0 while the google ad sets its alpha to 1. This fixes my problem in that if the iAd is white, it disappears and a google ad appears. But do I need to implement a shared ad? – Jameson Jun 08 '15 at 15:45
  • If your application has only one `view` that you wish to display a `ADBannerView` on then a shared banner is **not** needed. If you have multiple `view`'s you want to display your `ADBannerView` on a shared banner is **suggested**. I actually just finished writing a shared banner in Objective-C. You can view the answer [**here**](http://stackoverflow.com/a/30710028/2108547). – Daniel Storm Jun 08 '15 at 15:49
  • Thank you very much. And actually, I guess I was wrong. When I return from that rosters page, the iAd is still white/blank, even with this google ad implemented. Now there's a google ad for half a second, then it gets replaced by a blank iAd. – Jameson Jun 08 '15 at 15:55

0 Answers0