幾つかのアプリは,UIPopoverControllerとUIActionSheetを「明示的に閉じる」を実装していない(注1).それらを閉じるにはそれら外をタップすれば閉じるけど,指を遠くに動かさなければならない,かつ,アプリには色々なところにタップイベントが隠れているので,想定外の動作を引き起こす場合がある(注2).このインタフェースは致命的.有名どころのアプリでも,これを見る.ポップオーバー類は「開く」と「閉じる」をセットで実装してほしい.ちなみに,iPad用Safariはちゃんと実装している(さすがアップル!).(注3)
注1:「閉じる」に関してであり「閉じるボタン」ではない.領域外タップを期待して「閉じる」を自前で実装していないということ.
注2:無駄な動きが増えれば増えるほど誤動作が起こる確率は上がります.シングルタップのつもりが勢いあまってダブルやトリプルに.この話では,開ボタンに「閉じる」があれば,わざわざ指を領域外に移動させる必要がなくなるじゃないでか!
注3:本来アップルが求めるUIは「領域外のタップで閉じる」を求めている.開いたボタンも領域外となるが,そのボタンが「開く」しか制御してなければ,「閉じる」を期待してそのボタンを押しても結局開くだけになる.純正のSafariやMailが規定通り閉じるのに,一部サードがそれ従わないというのはどうしたものか,というお話.
例えばUIActionSheetの場合,visibleを確認すれば,1つのメソッド(1つのボタンだけ)でUIActionSheetの「開く」と「閉じる」を制御できる.下記はその一例.ちなみに,UIActionSheetを複数の用途で使い回すときは,下記コードを少し加筆しないとユーザーには優しくないよ.
----------
勘違いされた方がいたので追記(9/12)
----------
簡単に言い換えると,(コード例を見ても分かると思うけど)ポップオーバーのトリガーになるボタンを開ボタンだけでなく開閉ボタンにしろということです.開ボタンと閉ボタンの二つにしろという話ではありません(セットは独立って意味じゃないだろ・・・).試しに,今お使いのブラウザの「ファイル」ボタン(なければ,それ相応のモノ)を押してメニューを開いてください.さらに,そのボタンを押してください.ちゃんと閉じますよね,このことです.このメニューが閉じなかったら,不便だと感じませんか?.「俺なんか毎回別の場所をクリックして閉じてるぜ!」なんて人は少ないと思います.
タップイベントのことは,ユーザーは必ず規定のアクションをするのか?って話と関連します.手ぶれなんかする人間はいない!,机だけでしか使わない!と思っているなら今すぐ開発を辞めた方がいい.人間の行動には必ず不確実性が伴います.シングルタップを意図しても,ダブルタップになることがあるため,“想定外の動作を引き起こす場合がある”と書きました.特にこの場合,開ボタンから別の位置に移動するための速度(加速度)が指に加わるので,その可能性は上がります.他にも動画を見てもらえれば分かりますが,ポップオーバー中はすべてのタッチイベントが停止するわけではありません.ただ閉じたいと思ったのに,他のボタンを触ってしまって,想定外のアクションが起こる(動画では別のポップオーバーが開く)のはナンセンスです.ユーザーすべて,子供,大人,老人,障害者,・・・,があなたのような思考やスキルを持っているわけではありませんし,あなたも「絶対に間違えることはない!」とは言い切れないでしょう.
アプリはXcodeでビルドしてケーブルを繋いだMacの目の前で操作するものではありません.持ち歩いたり,横になったりして操作すると,開発者でも思いもしない操作が起こります.あなたが,俺のアプリはどんなユーザーでも誤動作を絶対にさせない!,痙攣していれもシングルタップとダブルタップを区別できる!(極端の例ですが)と言いきるならば関係のない話ですが,相手が人間ならば,それは不可能です.誤動作を引き起こす可能性があるならば,(100%は無理ですが)その可能性を出来る限り取り除くべきです.
Read more
注1:「閉じる」に関してであり「閉じるボタン」ではない.領域外タップを期待して「閉じる」を自前で実装していないということ.
注2:無駄な動きが増えれば増えるほど誤動作が起こる確率は上がります.シングルタップのつもりが勢いあまってダブルやトリプルに.この話では,開ボタンに「閉じる」があれば,わざわざ指を領域外に移動させる必要がなくなるじゃないでか!
注3:本来アップルが求めるUIは「領域外のタップで閉じる」を求めている.開いたボタンも領域外となるが,そのボタンが「開く」しか制御してなければ,「閉じる」を期待してそのボタンを押しても結局開くだけになる.純正のSafariやMailが規定通り閉じるのに,一部サードがそれ従わないというのはどうしたものか,というお話.
例えばUIActionSheetの場合,visibleを確認すれば,1つのメソッド(1つのボタンだけ)でUIActionSheetの「開く」と「閉じる」を制御できる.下記はその一例.ちなみに,UIActionSheetを複数の用途で使い回すときは,下記コードを少し加筆しないとユーザーには優しくないよ.
@interface HogeHoge : UIViewController
{
UIActionSheet *actionSheet;
}
@end
@implementation HogeHoge
-(IBAction)showActionSheet:(id)sender
{
if ( actionSheet.visible)
{
[actionSheet dismissWithClickedButtonIndex:-1 animated:YES];
return;
}
actionSheet = [[UIActionSheet alloc] ...];
[actionSheet showFromBarButtonItem:sender animated:YES];
}
@end
----------
勘違いされた方がいたので追記(9/12)
----------
簡単に言い換えると,(コード例を見ても分かると思うけど)ポップオーバーのトリガーになるボタンを開ボタンだけでなく開閉ボタンにしろということです.開ボタンと閉ボタンの二つにしろという話ではありません(セットは独立って意味じゃないだろ・・・).試しに,今お使いのブラウザの「ファイル」ボタン(なければ,それ相応のモノ)を押してメニューを開いてください.さらに,そのボタンを押してください.ちゃんと閉じますよね,このことです.このメニューが閉じなかったら,不便だと感じませんか?.「俺なんか毎回別の場所をクリックして閉じてるぜ!」なんて人は少ないと思います.
タップイベントのことは,ユーザーは必ず規定のアクションをするのか?って話と関連します.手ぶれなんかする人間はいない!,机だけでしか使わない!と思っているなら今すぐ開発を辞めた方がいい.人間の行動には必ず不確実性が伴います.シングルタップを意図しても,ダブルタップになることがあるため,“想定外の動作を引き起こす場合がある”と書きました.特にこの場合,開ボタンから別の位置に移動するための速度(加速度)が指に加わるので,その可能性は上がります.他にも動画を見てもらえれば分かりますが,ポップオーバー中はすべてのタッチイベントが停止するわけではありません.ただ閉じたいと思ったのに,他のボタンを触ってしまって,想定外のアクションが起こる(動画では別のポップオーバーが開く)のはナンセンスです.ユーザーすべて,子供,大人,老人,障害者,・・・,があなたのような思考やスキルを持っているわけではありませんし,あなたも「絶対に間違えることはない!」とは言い切れないでしょう.
アプリはXcodeでビルドしてケーブルを繋いだMacの目の前で操作するものではありません.持ち歩いたり,横になったりして操作すると,開発者でも思いもしない操作が起こります.あなたが,俺のアプリはどんなユーザーでも誤動作を絶対にさせない!,痙攣していれもシングルタップとダブルタップを区別できる!(極端の例ですが)と言いきるならば関係のない話ですが,相手が人間ならば,それは不可能です.誤動作を引き起こす可能性があるならば,(100%は無理ですが)その可能性を出来る限り取り除くべきです.