Monthly Archives: December 2015

エレベーターのボタンについて

UI理論101問題: このボタンは全て無くすことができますが、ひとつだけ残すとしたらどれでしょうか? pic.twitter.com/UFcG2h4PE8 — Manabu Ueno (@manabuueno) 2015, 12月 18 このツイートが意外にもたくさんRTされていたので、解説してみる。 UI設計理論としてはまず、「目的達成までのユーザーの運動と認知の負荷を減らす」という考え方をするのが基本だ。同じ結果を得るためなら、操作や選択肢は少ない方がよい。UIはユーザーにとってオッカムの剃刀であることが望ましい。 ただしシステムを利用して目的を達成するプロセスには「テスラーの複雑性保存の法則」というものがあり、入力しなければいけない情報を一定以上減らすことはできない。 一般的なエレベーターを利用する上で必要となる最低限のインプットは、次の6つだろう。 エレベーターを呼ぶ合図 乗るためにドアを開ける合図 乗った後にドアを閉める合図 行き先階 出発の合図 到着した際にドアを開ける合図 テスラーは、複雑性は減らせないが移動はできると言っている。必要なインプットの負担をユーザー側からシステム側に移動することで、ユーザーにとっての労力を減らすことができる。 一般的なエレベーターにおいては、上記の6つのうち、2, 3, 5, 6 については適当なタイミングで自動的に行われるようになっているので、ユーザーが行うのは 1 と 4 だけである。1 はエレベーター外の上下ボタン、3 はエレベーター内の階数ボタンを使ってユーザーがインプットする。 これらはユーザーが特定の階に移動するために必要な操作だが、実際にはこれらに加えて、自動化された動作をキャンセルする機能があるのが普通だ。すなわち次の2つ。 ドアが閉じようとするのをキャンセルする合図 一定時間を待たずにすぐにドアを閉じる合図 7 は開くボタン、8 は閉じるボタンで行われる。開くボタンについてはスプリング式になっていて、押し続けている間その合図が継続する。また開くボタンは、エレベーターが移動している最中には安全のためにディスエーブルになっている。ふたつ以上の合図が同時に発せられた場合は、安全な方に寄せて他は無視される。 開くボタンは、自動的に閉まろうとするドアに(自分を含めた)誰かが挟まれないよう、エレベーター内の人が押すためのもので、安全のためのスイッチだ。一方、閉じるボタンは、急いでいる人が早くエレベーターを出発させたい場合にのみ使うものであるため、重要度は低い。閉じるボタンが無いエレベーターも存在する。 またドアには通常、安全装置があり、物が挟まるとドアが開くようになっている。これに加えて、赤外線センサーによってドアに物が接触するのを防ぐ機能を備えているものも増えている。 … Continue reading

タッチジェスチャとコンストレイント

iOS には、あらかじめいくつかのタッチジェスチャを認識する API が用意されている。 ジェスチャとは、プリミティブな入力イベントの特定の組み合わせをひとつの意味として扱うものだ。例えばパソコンであれば、マウスボタンの押し下げ(マウスダウン)やそれを放すこと(マウスアップ)がプリミティブな入力イベントの例であり、このふたつを連続して一定面積内で行うと、クリックというジェスチャになる。一般的なマウスのジェスチャには他にも、ムーブ、ダブルクリック、ドラッグなどがある。 タッチデバイスではマウスのかわりにタッチイベントが用いられるが、プリミティブな入力としては、例えばタッチの開始や終了がある。指をスクリーンに触れて、それを一定面積内で放すと、タップというジェスチャになる。 iOS では、基本的なジェスチャとして次の7種類が想定されており、これらの動作を検出する API が用意されている。 タップ ピンチ ローテーション スワイプ パン スクリーンエッジパン ロングプレス それぞれには更に、指の本数や、動作の段階(ジェスチャが開始された、継続中、終了した)ごとに処理を変える仕組みが含まれている。 つまりタッチジェスチャは、マウスのジェスチャに比べて、バリエーションが多い。 バリエーションが多いと言っても、例えばダブルクリックがシングルクリックの二連続でできているように、ジェスチャによっては他のジェスチャの組み合わせでできているものもある。例えばスワイプジェスチャは、水平もしくは垂直方向に、一定以上のスピードでパンすることを意味している。 別な言い方をすれば、ある指の動作が、AのジェスチャなのかBのジェスチャなのかという判定は、マウスの場合に比べて、かなり微妙なものになっている。 また、同一画面上で同じ種類のジェスチャが複数の意味で実装されていることも多い。例えば iOS 9 のホーム画面では、水平方向のパンはアイコン一覧のページめくり、下方向へのパンは検索窓の表示、画面下辺付近からの上方向パンはコントロールセンターの表示、画面上部付近から下方向のパンは通知センターの表示、というふうに、いくつものパンジェスチャが実装されている。 複数のジェスチャを同一画面上に実装する場合は、通常、ジェスチャ同士に優先度をつけて、あるジェスチャが発動したら他のジェスチャはキャンセルされるようになっている。ホーム画面の例であれば、下方向へのパン操作が行われた時、それが画面上辺付近から開始されていれば、通知センター表示が優先され、検索ボックス表示の処理はキャンセルされる。 ジェスチャのバリエーションが複雑な分、こういった優先度づけやキャンセル条件などの処理は非常に入り組んだものになりがちだ。操作の示唆が暗黙的な分、ユーザーはうまく操作できないこともあるだろう。 Apple Watch のデジタルタッチ Apple Watch では、サイドボタンからフレンドを選んでデジタルタッチと呼ばれる特殊なメッセージを送信することができる。 デジタルタッチには三種類のモードがある。スケッチ、タップ、ハートビートだ。スケッチは指で線画を描くもの。タップはスクリーンをトントンと叩くもの。ハートビートは現在の心拍をモニターする。 これらのデジタルタッチは、リアルタイムに相手のウォッチ画面に表示される。タッチデバイスならではの非言語的なインスタントコミュニケーションだ。 デジタルタッチによるやりとりが実際に面白いかは置いておいて、その仕様はよくデザインされていると思う。 Apple Watch ではデザインガイドラインとして、ユーザーに複雑なことはさせるなと謳っている。デジタルタッチを送る時にも、送信ボタンを押したりモード変更の操作をする必要はない。 どのようにモードが決定されるのかというと、指でスクリーンをなぞる(パンジェスチャ)とスケッチモード、指でスクリーンを軽く叩くと(タップジェスチャ)タップモード、二本指でスクリーンを押さえつけると(二本指ロングプレス)ハートビートのモードになる。 … Continue reading

UITextView のタッチジェスチャと Textwell

UITextView のバグと対策 iOS 7 より UITextView の挙動が著しくおかしいということについて「iOS 7 のテキスト入力欄(UITextView)の問題について」に書いた。iOS 8 においても UITextView のバグは直されなかった。 iOS 9 が発表され、SDK をいじってみて、なんとなく直っているような気がしたが、それは気のせいだった。全体的には少しずつ改善されているように思うが、依然として振る舞いが安定しない。特に、カーソルがスクロール外の位置にある時に、ビューをカーソルが表示されるところまでスクロールさせるメソッドがうまく機能しないので、カーソルを見失ったような状態になりますい。この現象は純正アプリも含めて、UITextView を使った色々な箇所で見受けられる。 私がプロダクトマネージャーをつとめる Textwell の iOS 版では、UITextView のバグを回避するための補正処理として、具体的に、以下のメソッド/プロパティをオーバーライドしている。 ・scrollRangeToVisible: カーソルが見える位置までビューをスクロールするメソッドだが、テキストレンジの座標が正しく計算されていないようなので、自前でそれを計算し直し、”scrollRectToVisible:animated:” に投げる。 ・closestPositionToPoint: 特定の座標に一番近いテキストポジションを返すメソッド。タッチジェスチャとテキスト処理の橋渡しをする重要なメソッドだが、時々おかしな値を返してくるので、レイアウトマネージャーのグリフ情報を使って正しいポジションを返すようにする。 ・layoutManager.allowsNonContiguousLayout デフォルトでは NO だがこれを YES にする。 ・layoutManager.hyphenationFactor デフォルトで 0 のはずだが、何かの拍子に値が変わるのかもしれない。0 に指定し直すと挙動がましになる気がする。 … Continue reading