iAd を画面下に固定する方法

UITableView を画面いっぱいに表示し、広告を画面下に表示するというのは、 よくある組み合わせだと思う。

このとき、UITableView をスクロールしても、広告は画面下に固定して、ずっと表示していたい。 ただし、Apple の審査に通るために、広告の取得に失敗したら広告を非表示にしないといけない。 あと、取得するまで広告の部分が空白なのは見た目が悪いので、取得できるまで非表示にしておきたい。

上記をストーリーボードだけで実現しようとしたけど、力及ばず。 仕方なくコードで実現した。 今後何度も書くこと間違いないので、やり方をメモしておく。 動作は iOS7 で確認。

#import <iAd/iAd.h>
#import "MasterViewController.h"

// ADBannerViewDelegate プロトコルを実装
@interface MasterViewController () <ADBannerViewDelegate>

@property (nonatomic) ADBannerView *bannerView;
@property (nonatomic) BOOL isShowAd;

@end

@implementation MasterViewController

...

- (void)viewDidLoad
{
  [super viewDidLoad];

  self.isShowAd = NO;

  // 画面外に広告を配置しておく
  self.bannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0,
                                                                   self.view.frame.size.height,
                                                                   0,
                                                                   0)];
  self.bannerView.delegate = self;
  [self.view addSubview:self.bannerView];

  // 一番下のセルが広告に隠れないように空のフッターを追加
  self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0,
                                                                            0,
                                                                            0,
                                                                            self.bannerView.frame.size.height)];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  if (self.isShowAd)
  {
    // スクロールしても、常に画面下に広告を表示する
    CGRect frame = [[UIScreen mainScreen] application
    float statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
    float viewHeight = frame.size.height;
    float adViewWidth = self.bannerView.frame.size.width;
    float adViewHeight = self.bannerView.frame.size.height;

    self.bannerView.frame = CGRectMake(0,
                                       viewHeight - adViewHeight + statusBarHeight,
                                       adViewWidth,
                                       adViewHeight);
    [self.view bringSubviewToFront:self.bannerView];
  }
}

// 広告を取得できたら画面下に広告を表示する(アニメーション付き)
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
  self.isShowAd = YES;

  CGRect frame = [[UIScreen mainScreen] applicationFrame];
  float viewHeight = frame.size.height;
  float statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
  float adViewWidth = self.bannerView.frame.size.width;
  float adViewHeight = self.bannerView.frame.size.height;

  [UIView animateWithDuration:1.0
                        delay:0.0
                      options:UIViewAnimationOptionCurveEaseInOut
                   animations:^{
                     self.bannerView.frame = CGRectMake(0,
                                                        viewHeight - adViewHeight + statusBarHeight,
                                                        adViewWidth,
                                                        adViewHeight);

                     self.bannerView.alpha = 1.0;
                   }
                   completion:nil];
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
  self.isShowAd = NO;
}

...

@end

結構面倒くさい。AutoLayout を使ってスマートにやれるといいんだけど。