2012年5月アーカイブ

こんにちは。開発担当のICTFです。

新しいアプリケーションを開発するにあたり、tableViewで表示する広告の配置方法を少し工夫したいと考えていました。
具体的には、
 ・セルの最後尾に1セル追加する様なイメージで広告を表示する。
 ・セルのイメージではあるが、決してテーブルビューから隠れないようにする
  (他のセルの上に描画し、最後尾セルが画面外に配置されるケースでは、tableViewの下部分に張り付く様にしたい。)
といったような感じです。

2つ目の条件を満たすのに苦労したのですが、UITableViewに始めから備わっているある機能を利用することでかなり楽に実装ができたので、今回はその方法を書こうと思います。
本来の使い方とかけ離れていますが、UITableViewに最初から用意されているセクションフッターを今回は用います。

セルとしての動作もするため、tableViewがスクロールする際に広告が再読み込みされる可能性があります。
再読み込みの無駄を無くす為、まずはUITableViewControllerのメンバーに広告ビューへの参照をメンバとして追加します。

[adList.h]

@interface adList : UITableViewController

{

UIView* _adView;

}


次に.mの修正に入ります。
広告ビューのretainなどが面倒なので、プライベートなinterfaceに_adViewのプロパティを追加します。

@interface adList ()


@property (nonatomic, retain, readwrite) UIView* AdView;


@end


implementationでプロパティとメンバを忘れずに接続します。

@implementation adList


@synthesize AdView = _adView;

...


ここまでで下準備は終了です。
実際に広告ビューを画面に表示する為の処理ですが、-(UIView*) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section内に記述します。
このメソッドはUITableViewがセクションフッターを表示するタイミングで自動的にコールしてきますので、戻り値として広告ビューを返すようにします。

// セクションのフッタービューを返す

-(UIView*) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

{

    if (self.AdView == nil) {

        // 広告を表示する

        UIView* adView = [[CommonResources sharedCommonResources]                 getAdViewOnRootViewController:self];

        self.AdView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0,

        self.view.frame.size.width, adView.frame.size.height)]

        autorelease];

        self.AdView.backgroundColor = [UIColor colorWithRed:1.0 

        green:1.0 blue:1.0 alpha:0.5];

        [self.AdView addSubview:adView];

        adView.center = self.AdView.center;

}

return self.AdView;

}



上記の例ではUIViewを生成し、その上に広告ビューを載せています。
これは広告ビューの大きさが必ずしもtableViewの幅と一致する訳ではないので、その余白をどのように表現するかに自由度を持たせる為です。
単に表示するだけでよければ、self.AdViewにそのまま広告ビューのポインタをセットしても構いません。

次にセクションフッターの高さを返すメソッド-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)sectionを実装します。
このメソッドを実装し忘れると、広告が中途半端に表示される様な事態になりますので気をつけてください。

// セクションフッターの高さを返す

-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section

{

if (self.AdView == nil) {

// セクションフッタービューが生成されていない場合、まず生成する

[self tableView:tableView viewForFooterInSection:section];

}

return self.AdView.frame.size.height;

}


念のため広告ビューがまだ生成されていなかった場合の対策を含めています。

これで完成です。
複数のセクションを含むtableViewで広告を表示する場合、上記2つのメソッド内で引数sectionを参照し、必要がなければnilを返したり、高さ0を返すようにしてみてください。

結構面白い動作をしてくれますので、是非一度お試しください。
広告だけではなくUIView全般に使えるテクニックですので、もっと面白いこともできるかもしれませんね。
こんにちは。開発担当のICTFです。

あるエラーチェック処理で、各エラーが起きた際にユーザに表示するエラーメッセージを数百種類用意する事になりました。
メッセージ自体は定型的で、「xxxが間違っています。」と言った類いのものなので、xxxの箇所を動的に作成すればすぐ終わりそうな内容です。
例えばこんな感じに書けば終了ですね。

NSString* message = [NSString stringWithFormat:@"%@が間違っています。", sentence];

ただ今回はこのエラーメッセージをさらに他言語対応しなければなりませんでした。
現在の言語環境を取得し、各言語に対して上の例の様に文字列を作成する処理を記述すれば作れはするのですが、折角XCodeにはローカライズ対応の為の機能があるのですし、それを使って格好よく実装できないかと思っていました。
そこで、試しにstringWithFormatのフォーマット部分にNSLocalizedStringで得た文字列を渡してみたところ上手く動作しましたので、その手順を書いておこうと思います。

まず日本語と英語の2カ国語に対応する場合、ローカライズ用の2つのファイルが必要になります。
en.lproj/Localizable.strings  英語用
ja.lproj/Localizable.strings  日本語用
この辺りはマニュアルにも載っていますね。

次に英語用のLocalizable.stringsに次の記述を追加します。
"SYS_ERR001" = "%@ is incorrect.";
日本語用のLocalizeble.stringsには次の記述を追加します。
"SYS_ERR001" = "%@ が間違っています。";
%@は普通にフォーマットを指定して動的文字列を作成するときの%@と同じです。

使用法は以下の通りです。
NSString* message = [NSString stringWithFormat:NSLocalizedString("SYS_ERR001", nil), sentence];

これだけでメッセージを作る前に原語環境を調べたり、対応言語分の分岐を用意する必要は無くなります。