UIAlertViewのカスタマイズ「addTextFieldWithValue:label:」を乗り越える その1

アプリも完成間近にさしかかり、深刻なエラーはないものの、警告が多かったのでそれをつぶしにかかる。
あれこれ調べているうちに「addTextFieldWithValue:label:」というメソッドが非公開APIという位置づけにある事を知った。
ということは、リジェクトを食らうってこと?


TextFieldからの値を取得したり、レイアウトを決めるのには元々のUIAlertViewをカスタマイズしたクラスを作れる必要があるんだろうなと思っていたところに、ちょうどいいものを発見!

「TextAlertView.m」
http://discussions.apple.com/message.jspa?messageID=8445879#8445879

すでに誰かが作ってくれているならこれを参考に作っちゃいましょう♪


中を見てみると、

  • (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate

cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...;
にて TextField付きのUIAlertViewを作っている事が分かる。



呼び出しもとはこんな感じ

TextAlertView *alert = 
[[TextAlertView alloc] initWithTitle:@"title" message:@"message"
			   delegate:self
			cancelButtonTitle:@"Cancel"
			otherButtonTitles:@"Add",nil];
[alert show];

ボタンを押されたときのアクションはこれ,でもTextFieldの値を取得している部分で警告になっちゃうのね。もしかすると、ここもカスタマイズが必要かもしれない。

-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
	switch (buttonIndex) {
		case 0:
		   break;
		case 1:
			Text = [[alertView textField] text];
			
			if([appDelegate.timerName length]<1){
				UIAlertView *alert = [[UIAlertView alloc] init];
				alert.delegate = self;
				alert.title = @"title";
				alert.message = @"message No input";
				[alert addButtonWithTitle:@"OK"];
				[alert show];
				return;
			}
			[self addBookmark];
			 
			break;
	}
	
}

さらに layoutSubview でレイアウトを整えている。イニシャライズされた後に呼ばれている事が分かる。
素直に実行してみるとうまくいかない。
横向きのアプリを作っているからかもしれないけれど、修正が必要な箇所は以下のとおりでした。

  1. タイトルがアラートの枠からはみ出ている。
  2. TextFieldの横幅がアラートを突き抜けている。
  3. ボタンの位置が高すぎる


どうすればカスタマイズできるか?
[alertView subViews]objectAtIndex:i]でオブジェクトを拾って来れる事が分かった。
参考
http://viksiphoneblog.blogspot.com/2010/08/how-to-customize-alert-view.html

どれがどのオブジェクトさえ分かれば

[[[alertView subviews] objectAtIndex:4] setTitleColor:[UIColor grayColor];

とかで色とかサイズを決めていってしまえばいい。


そこでTextAlertViewのlayoutSubviewsメソッドの中身をいじってみることに。
下のコードだとラベルから高さを決定していく。


for(UIView *view in self.subviews)でオブジェクトを拾ってきて
if ([view isKindOfClass:[UILabel class]]) にてクラス判定している部分があるので
ここで位置などを書き換えてみる。

あれれ?何かおかしい?
if ([view isKindOfClass:[UIButton class]])
で引っかかってくるオブジェクトがない?
もちろんObjectAtIndexで指定して行けばいいんだけれど、Indexは{枠、タイトル、メッセージ、キャンセルボタン、ボタン ×n、テキストフィールド}の順になるのでボタンを増やしたときに対応できなくなってしまう。
なので、やはりfor(UIView *view in self.subviews)の中でクラスを判定して
レイアウトを整えたい。

オブジェクトの数をNSLog(@"%d",[[self subviews]count]); で調べると6個だった。
タイトル、メッセージ、テキストフィールド、OKボタン、キャンセルボタン、アラートの枠だとすると6個でつじつまが合う。
layoutSubviewsを実行した感じでは、UILabelとUITextFieldは拾って来れているみたいだ。
あとは、ボタン2つと枠を拾ってこれればよい。

つかれたので次回へ続く。