RSS

iPad: UIPopoverControllerとUIActionSheetは閉じてくれ

幾つかのアプリは,UIPopoverControllerとUIActionSheetを「明示的に閉じる」を実装していない(注1).それらを閉じるにはそれら外をタップすれば閉じるけど,指を遠くに動かさなければならない,かつ,アプリには色々なところにタップイベントが隠れているので,想定外の動作を引き起こす場合がある(注2).このインタフェースは致命的.有名どころのアプリでも,これを見る.ポップオーバー類は「開く」と「閉じる」をセットで実装してほしい.ちなみに,iPad用Safariはちゃんと実装している(さすがアップル!).(注3)

注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%は無理ですが)その可能性を出来る限り取り除くべきです.

Bookmark and Share

8 コメント:

匿名 さんのコメント...

>幾つかのアプリは,UIPopoverControllerとUIActionSheetを「明示的に閉じる」を実装していない.それらを閉じるにはそれら外をタップすれば閉じる

Apple のインターフェイスガイドラインはこれを推奨しています。

>かつ,アプリには色々なところにタップイベントが隠れているので,想定外の動作を引き起こす場合がある.

標準の状態で、ポップオーバーが表示されている時にはポップオーバー外をタップしても、そこにあるビューにはタッチイベントが届かないようになっているので、想定外の動作を引き起こすことはありません。

>iPad用Safariはちゃんと実装している(さすがアップル!).

iPad の Safari も、ポップオーバーに閉じるボタンは配置してませんが(ブックマーク表示など。)

mitsuharu さんのコメント...

もしかして,一つのポップオーバーに開くボタンと閉じるボタンの二つを用意しろと勘違いしてるのでしょうか?.それなら大きな勘違いです.当たり前ですが,そんなアホな実装はしたことがないです.

文章とコードを見たら分かると思いますが,一つのボタンで開閉をしろということです.試しにSafariのブックマークボタンを押してポップオーバーをして,さらにそのボタンを押してください.閉じるでしょ.他のアプリでも試してみてください,必ず閉じてくれますか?.

タップイベントのことは,人は必ず規定のタップ数をすることを確約できますか?.寝転がったり,姿勢が悪かったりすると,シングルタップがダブルタップになる可能性はゼロではありません.人間は絶対に誤動作をしない!とあれば良いのですが,人間の動作には必ず不確実性が伴います.一つの「開いた」だけに満足せずに他イベントとも関連して起こりうる誤動作を出来る限り少なくするUIを設計することが必要です.

というか,閉じるためにわざわざ指を遠くに持って行くのが,億劫だと思いませんか?.少なくとも,私は億劫だし,そんなアプリは気持ち悪く思います.

匿名 さんのコメント...

あなたの主張は、「ポップオーバー外をタップしても、ポップオーバーが閉じないようにすべき」なんですか?

たとえばポップオーバーを開くボタンをタップして閉じるようにしたところで、ユーザーが「ポップオーバー外をタップすることで閉じる」という動作をすれば、あなたのいう

>人は必ず規定のタップ数をすることを確約できますか?.寝転がったり,姿勢が悪かったりすると,シングルタップがダブルタップになる可能性はゼロではありません」

という問題はやっぱり起きる訳ですよね。

もしかして、ユーザーに開閉ボタンを使ってポップオーバーを閉じることを強要するんですか?

かつ、ポップオーバー外をタップすることでポップオーバーが閉じるように作ってあれば、やはりポップオーバーを開いたボタンも「ポップオーバー外」に存在するので、何の問題もなくポップオーバーは閉じるんです。

匿名 さんのコメント...

ゲンナリすることはあっても、タメになることはありませんでした(笑)

匿名 さんのコメント...

ゲンナリすることはあっても、タメになることはありませんでした(笑)

mitsuharu さんのコメント...

勘違いが加速しているようですね.どうしてこう噛み合わないのかが不思議です.でも,ベクトルがあえば,楽しい建設的な話ができそうだ.

>あなたの主張は、「ポップオーバー外をタップしても、ポップオーバーが閉じないようにすべき」なんですか?

最初から言ってますが,「開く」に「閉じる」も付けてくれという考えだけです.閉じ方を一方的に制限する話ではありません.

PCのスイッチ,ブラウザのメニュー,蛍光灯のスイッチ,・・・,開閉(ON-OFF)は実生活でもペア(同位置)で扱われることが多いですよね.閉じようとして習慣で「開くボタン」の所を押して閉じなかったら,違和感を感じませんか?.iPadユーザー全員は必ずポップオーバー外をタップして閉じるのであれば,なぜSafariは「閉じる」も実装しているのですか?.習慣で開閉ボタンと考える人もいるからこそ(私はこっち側),「閉じる」に自由度を足してくれという話です.

おそらく,ツッコムであっろう不確実性の話.

車でブレーキとアクセルを間違えて踏んで,期待する動作が起こらなかったことでパニックになって事故が起こったというニュースを聞いたことがあると思います.スケールは違いますが,私は開閉ボタンにすることで,踏み間違える(ポップオーバーが閉じないよ)を少なくして,パニック(どうしたら閉じるんだ,そうだ連打しよう)を少なくしようとしているだけ.

特に純正Safariは開閉を実装しいるのに,サードが違う動作をしたら違和感を感じる人(連打する人)もゼロじゃないと思います.どうですか?.もし,ゼロというデータがあるなら是非私も見たい!

そして,これを使うか使わないかはユーザーしだい.iPadに慣れた人ならポップオーバー外をタップしたい人もいる.その人たちは最初から「ここをタップしたら閉じる」と意識してるから,誤動作は少ないと考える.データは持ってないけど,そう思いませんか?


>たとえばポップオーバーを開くボタンをタップして閉じるようにしたところで、ユーザーが「ポップオーバー外をタップすることで閉じる」という動作をすれば、あなたのいう

勘違いしないで欲しいけど,私はポップオーバーの「閉じる」を開閉ボタンとポップオーバー外タップで制御してる.だから外をタップしたら,まずは閉じる.そして,そのタップの勢いが止まらなくて,下にイベントがあれば誤動作は起こる.けど,前に書いたとおり,ポップオーバー外をタップすれば閉じると知っていれば,比較的誤動作は少ないと割り切ってる.これはどのアプリでも抱える問題でしょ.まぁでも,私もよく寝転がって操作するから,よく勢いがとならないときがあるけど(笑)



>かつ、ポップオーバー外をタップすることでポップオーバーが閉じるように作ってあれば、やはりポップオーバーを開いたボタンも「ポップオーバー外」に存在するので、何の問題もなくポップオーバーは閉じるんです。

意味が分からないことが二つあるので教えてください.

(1)前半の「ポップオーバー外をタップすることでポップオーバーが閉じるように作ってあれば、」というのは,どういう意味でしょうか?.追加コードをしなくても閉じると思いますが,何か追加しているのですか?.私は何も特別なコードは追加したことはありませんが,ポップオーバー外のタップで閉じてくれます.

(2)後半の"開いたボタンも「ポップオーバー外」に存在するので..."についてです.動画後者のアプリは「ポップオーバー外をタップして閉じるアプリ」ですが,動画の通り「開くボタン」で閉じませんでした.これはどういうことですか?.また,ポップオーバー外の別ボタンの所を押すと閉じますが,別のポップオーバーが開いて,結局閉じてくれません(目的が別のポップオーバーを開くならOKですが,この例は「閉じたい」なのでNGです).さらに,動画最後でさらにポップオーバー外隣のテキストの場所をタップしたのですが,閉じません.どういうことですか?.他の有名どころのアプリでも確認しましたが,ポップオーバー外では消えますが,開いたボタンでは閉じませんでしたよ!

「そのように実装してる!」と返ってきそうですが(笑),最初から,私はその「開きっぱなし」が使いにくいと言っているだけです.あなたが作るポップオーバー管理は,どこでも閉じるという凄いコードのようで,ぜひ無知の私に教えてください.

mitsuharu さんのコメント...

人間の不確実性を考えたことがないようなので,少しはタメになったんじゃないんですか?(笑)

今朝Mailを使ったのですが,左上のメールボックスボタンが開閉式だったので楽でした.私は,親指を前に,他4本を裏に回して持つので,親指の可動範囲が限られます.この開閉ボタンにはとても重宝してます.これがポップオーバー外だけしか受け付けないとなると,わざわざ持ち手を左から右に変えないといけないし,間違えて右手のコーヒーがこぼれたらどうしようかと思いましたよ.

さてさて,ちょっと気になるなのですが,なぜ最初に「閉ボタン」と勘違いされたのでしょうか?

最初の数行だけなら私が閉ボタンの設置を推奨しているように思えなくはないですが,Safariの例で不思議に思いませんでしたか?.無いものを例に出している時点で,さすがに閉ボタン説が変だと.もちろん薬はやってないので幻覚は見ないよ(笑)

私は違った意図に取られないようにと,わざと意識して「開閉をセットで」と書きました(以前も開と閉を独立と勘違いした方がいたため).さらに念のためコード例も示して,一つのメソッドで開閉を一緒に扱うことを書いていますし,わざわざ「1つのメソッド(1つのボタンだけ)で・・・」と書いてある時点でボタンは一つであることを強調しています.

この話に食いつくのはiPadアプリの開発者だけだろうし,説明が多少下手でもコード例を見れば言わんとすることはわかるだろうと思っていたのですが,まったくもって不思議です.

mitsuharu さんのコメント...

やっと意味が分かった,「枠外の開いたボタンでも閉じる」の話.アップルは枠外タップで閉じるのを望んでいて,もちろん開いたボタンも枠外にある.でも,一部アプリのボタンは「開く」を優先するから,結局アップルが望む枠外で閉じるができない.うん,やっぱり,枠外の領域をユーザーに制限させないため,開閉が必要ってことだな.