Hatena::Groupiphone-dev

Ni chicha, ni limona -- paellaの日記

2009-11-06嬉しいことと、お詫びしなければいけないこと

[iPhone][Develop][Metronome] UITabBarControllerなどでUIActionSheetを使う場合の注意点と、お詫び 19:50  [iPhone][Develop][Metronome] UITabBarControllerなどでUIActionSheetを使う場合の注意点と、お詫び - Ni chicha, ni limona -- paellaの日記 を含むブックマーク はてなブックマーク -  [iPhone][Develop][Metronome] UITabBarControllerなどでUIActionSheetを使う場合の注意点と、お詫び - Ni chicha, ni limona -- paellaの日記  [iPhone][Develop][Metronome] UITabBarControllerなどでUIActionSheetを使う場合の注意点と、お詫び - Ni chicha, ni limona -- paellaの日記 のブックマークコメント


※(2009/12/1追記)UITabBarControllerを使う場合は、わざわざグローバル変数を使わなくてもself.tabBarController.viewで同じviewを渡せることが分かりました。 @monokakido さん、ご助言ありがとうございました。

UIActionSheetを使うと、画面の下からニュルッと選択項目が出てきて、ユーザーに行動を選ばせることができます。

このシートを使うときの注意点を記録しておきます。

概要

UITabBarControllerなどの画面下部を使うコントローラでUIActionSheetを表示するときは、大元のコントローラのviewをshowInView:メソッドに渡すこと。タブ内のビューのviewを渡さないこと。

発生する現象

表示されたシートのうち、表示対象にしたビューのframe部分しかタップに反応しなくなります。

詳細

UIActionSheetを表示させるときは同インスタンスに対して、showInView:メソッドで表示対象のviewを渡します。

	UIActionSheet *actionSheet = [[UIActionSheet alloc]
								  initWithTitle:@"Select an action:"
								  delegate:self
								  cancelButtonTitle:@"Cancel"
								  destructiveButtonTitle:nil
								  otherButtonTitles:@"Foo", @"Bar", nil];
	actionSheet.actionSheetStyle = UIBarStyleBlackTranslucent;
	[actionSheet showInView:targetView];
	[actionSheet release];

しかしこのときのは挙動を見る限りでは、どのビューに入れたとしても画面最下部からシートが現れるようです。

たとい真ん中辺りにだけ表示するビューであったとしてもです。そのため、表示対象として渡したビューのframe外の部分についてはイベントに反応しなくなってしまいます


   f:id:paella:20091106194348p:image


ですのでUIActionSheetを使用する場合には、大元のビューコントローラのviewに表示させてあげないといけません。

私の場合はUITabBarControllerを使用していましたので、AppDelegate相当のクラスでUITabBarControllerを保持しておき、そのviewに表示させるようにして対処しました。

self.tabBarController.viewで大丈夫です。グローバル変数相当の情報を使う必要はありませんでした。失礼しました。

	UIActionSheet *actionSheet = [[UIActionSheet alloc]
								  initWithTitle:@"Select an action:"
								  delegate:self
								  cancelButtonTitle:@"Cancel"
								  destructiveButtonTitle:nil
								  otherButtonTitles:@"Foo", @"Bar", nil];
	actionSheet.actionSheetStyle = UIBarStyleBlackTranslucent;
	// AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
	// [actionSheet showInView:appDelegate.rootController.view];
	[actionSheet showInView:self.tabBarController.view];
	[actionSheet release];

これで、最下段でタブ内ビューのframe外に相当する部分もイベントを拾ってくれるようになりました。


まとめ(お詫び)

UIActionSheetを使うときは、画面全体を覆うビューに対して表示させること。


−−− Metronome for Professionalで、ブックマークタブでブックマークを選択したときにCancelボタンの反応が非常に悪い不具合がある、という報告を頂きました。原因を調査したところ、上記がその理由だと分かりました。

現在、BugFixしたマイナーアップデート版を慌てて作成しています。

回避策は今のところ「Cancelボタン上の、タブバーの幅に被らない部分をタップする」しかありません。


ご購入頂いた方、ご迷惑をおかけしており誠に申し訳ありません。ver.1.1で修正しましたので、アップデートしてご利用ください。

tokoromtokorom2009/11/08 00:44showInView:じゃなくて、showFromTabBar:のほうを使えば大丈夫かもしれません。

paellapaella2009/11/08 01:33コメントありがとうございます。なるほど、showFromTabBar:には気付きませんでした。ドキュメントには更にshowFromToolBar:なんてのもありますね。

- (void)showFromTabBar:(UITabBar *)view

ただ、UITabBarより上に出すとなると状態遷移が更に増えてしまって大変そうなので、今回はShowInViewにすることにします。
役立つ情報を教えていただいて、ありがとうございました。

AppleWalkerAppleWalker2009/11/08 12:10こんにちは。
いつもお世話になってます。
前に、この問題にはまってブログにTipsを書きました。
よかったら、参考にしてみてください。

http://applewalker.blog8.fc2.com/blog-entry-51.html

paellapaella2009/11/10 00:07AppleWalkerさん、ありがとうございます。他の例も画像ででていて、とても参考になりました。
Twitterでも結構多くの方がハマっていた振る舞いのようですね。frameはついうっかりが多いので、有効なビュー領域を可視化できればいいんですけどね。