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