Long Press(ロングプレス)は、指を一定時間(通常0.5~1秒)画面に触れたまま動かさない長押しジェスチャーです。Tapとは異なり、Long Pressはタッチの瞬間ではなく、遅延タイマーが切れた後に認識されます。このジェスチャーは、コンテキストメニューの表示、コンテンツのプレビュー、複数オブジェクトの選択、追加アクションの起動に使用されます。iOSではUILongPressGestureRecognizer、AndroidではsetOnLongClickListenerまたはGestureDetectorを介して実装されます。
重要なポイント
Long Press(ロングプレス、長押し)は、ユーザーが画面に触れ、指を一定時間動かさずに保持するマルチタッチインターフェースのジェスチャーです。システムは即座に反応せず、タイムアウト(通常500ms)を待ち、それが経過した後にのみジェスチャーをLong Pressとして認識します。指が早く離された場合は、通常のTapとして解釈されます。
このジェスチャーは、現代のモバイルインターフェースの基本的な構成要素です。Appleはアプリ(Messages、Safari、Files)でコンテキストメニューを呼び出すためにこれを使用します。GoogleはAndroidのテキスト選択、ホーム画面のアイコン再配置、コンテキストメニュー呼び出しにLong Pressを採用しました。Webインターフェースでは、物理的な右ボタンがないモバイルデバイスで、長押しはしばしばマウスの右クリックをエミュレートします。
歴史的には、Long Pressはタッチスクリーン用のコンテキストメニュー(右クリック)の代替として登場しました。初期の実装は抵抗膜式スクリーンを搭載したデバイス(Palm、2000年代初頭のWindows Mobile)に見られましたが、ジェスチャーが標準化されたのはiPhoneとAndroidの登場以降です。両プラットフォームのヒューマンインターフェースガイドラインは、Long Pressを二次的なアクションとして説明しています—Tapの代替ではなく、機能の拡張としてです。
Long PressとTapは、異なるセマンティクスを持つ2つの異なるジェスチャーです。Tapは瞬間的なタッチで、指が画面に触れて100~300msで離されます。Tapは常にプライマリアクションです:アプリを開く、ボタンを押す、リンクをたどる。Long Pressはセカンダリアクションです:コンテキストメニューを開く、編集を開始する、追加情報を表示する。
| パラメータ | Tap | Long Press |
|---|---|---|
| 長押し時間 | 100~300ms | 500~1000ms |
| アクションの種類 | プライマリ | セカンダリ |
| 例 | リンクを開く、ボタンを押す | コンテキストメニュー、編集 |
| フィードバック | 視覚的(ハイライト) | 触覚的(Haptic Feedback) |
| iOS API | UITapGestureRecognizer | UILongPressGestureRecognizer |
| Android API | setOnClickListener | setOnLongClickListener |
重要なルール:Long Pressをアクションを実行する唯一の方法として決して使用しないでください。ユーザーはTapがプライマリアクションを実行し、Long Pressが追加オプションを開くことを期待しています。この原則に違反すると(例えば、リンクを開くために長押しを要求する)、ネガティブなユーザー体験とアクセシビリティの低下につながります。
UILongPressGestureRecognizerは、長押しを処理するためのiOS SDKの標準ジェスチャー認識クラスです。UIGestureRecognizerを継承し、最小持続時間、許容される指の移動、タッチ数の設定をサポートします。認識機能は、タイマーが切れるとUIGestureRecognizerStateBegan状態に移行し、指が動くとUIGestureRecognizerStateChanged、指を離すとUIGestureRecognizerStateEndedに移行します。
// 最小持続時間を設定したUILongPressGestureRecognizer
class ContextMenuViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let longPressRecognizer = UILongPressGestureRecognizer(
target: self,
action: #selector(handleLongPress(_:))
)
// 最小長押し時間:0.5秒
longPressRecognizer.minimumPressDuration = 0.5
// 許容される指の移動:10ポイント
longPressRecognizer.allowableMovement = 10
customView.addGestureRecognizer(longPressRecognizer)
}
@objc func handleLongPress(_ recognizer: UILongPressGestureRecognizer) {
guard recognizer.state == .began else { return }
// コンテキストメニューの作成
let location = recognizer.location(in: self.view)
ContextMenuPresenter.show(at: location)
}
}設定パラメータ:minimumPressDuration — 起動までの秒数(デフォルト0.5、アクセシビリティの場合は0.65以上推奨);allowableMovement — ポイント単位の指の最大移動量(デフォルト10、手の震えがある場合は増やすと効果的)。iOSはマルチタッチジェスチャー用のnumberOfTouchesRequiredをサポートしています(例:2本指での長押し)。認識機能はUIContextMenuInteractionとも統合されており、UIContextMenuConfigurationを介してUIViewにコンテキストメニューが追加されると、Long Pressは手動のジェスチャー実装なしで自動的にコンテキストメニューを呼び出します。
setOnLongClickListenerは、Android SDKのViewメソッドで、長押しリスナーを設定します。ユーザーがViewを500ms以上長押しすると、システムはonLongClick()を呼び出します。このメソッドはbooleanを返します — trueはイベントが処理され、それ以上伝播しないことを意味し、falseはイベントが他のリスナーによって処理される可能性があることを意味します。より複雑な処理(Long Press開始後の指の移動)には、OnGestureListener付きのGestureDetectorが使用されます。
// 触覚フィードバック付きsetOnLongClickListenerの例
val itemView: View = findViewById(R.id.itemView)
itemView.setOnLongClickListener {
// ジェスチャー開始を確認するための触覚応答
it.performHapticFeedback(
HapticFeedbackConstants.LONG_PRESS
)
// 要素の位置にコンテキストメニューを表示
val popup = PopupMenu(this, it)
popup.menuInflater.inflate(R.menu.context_menu, popup.menu)
popup.show()
true // イベント処理済み
}GestureDetectorは、ジェスチャーをより細かく制御します。setOnLongClickListenerとは異なり、GestureDetectorは開始(onLongPress)、移動(onScroll)、解放を通知します。これにより、複雑なシナリオが可能になります — 例えば、長押し後のドラッグ開始(Drag-and-Drop)。OnGestureListenerでは、onDown、onShowPress、onSingleTapUp、onScroll、onLongPress、onFlingの6つのメソッドを実装する必要があります。
Long Pressは、数十のモバイルインターフェースシナリオで使用されています。最も一般的な用途はコンテキストメニューです:連絡先を長押しすると通信オプション(電話、メッセージ、メール)が表示され、ファイルではオプション(コピー、移動、削除)、テキストでは選択とクリップボードが表示されます。Android Launcherは、アプリの移動やウィジェットの追加にアイコンの長押しを使用します。
テキスト選択は、両プラットフォームにおけるLong Pressの典型的な例です。iOSでは、テキストを長押しするとカーソル位置決め用の拡大鏡がアクティブになり、単語の上ではハンドル付きで選択されます。Androidでは、長押しで単語全体が選択され、アクションバー(コピー、カット、ペースト)が表示されます。両プラットフォームとも、ハンドルをドラッグして選択範囲を拡張します。
プレビュー — iOSでは、SafariのリンクやMailのメッセージを長押しすると、コンテンツのプレビュー(peek)が開きます。Androidでは、同様の動作が通知のLong Pressを介して実装されています(アクションボタン付きで通知を展開)。写真アプリでは、サムネイルを長押しして画像をすばやくプレビューします。
ドラッグ&ドロップは、多くの場合Long Pressで開始されます。ユーザーが要素を長押しすると、システムはドラッグモードに切り替わり、指の動きに合わせて要素が画面上を移動します。AndroidはLong Press後のView.startDragAndDrop()を介してこのシナリオをサポートします。iOSはUIDragInteractionを使用し、ドラッグインタラクションにはドラッグ開始のための長押しが必要です。
両プラットフォームのヒューマンインターフェースガイドラインは明確な推奨事項を提供しています:Long Pressは常にセカンダリアクションであるべきです。重要な機能を実行する唯一の方法として長押しを使用しないでください。ユーザーは最初にTapを試みます — Tapが期待通りに機能しないと、ユーザーは不満を感じます。視覚的な手がかりを追加しましょう:コンテキストメニューは三点リーダーアイコンで示し、Long Pressをサポートする要素はタッチ時に視覚的なヒントで示すことができます。
触覚フィードバックはLong Pressに必須です。ジェスチャーが認識されると、デバイスは触覚応答で確認する必要があります:iOSでは軽いインパルスのUIImpactFeedbackGenerator、AndroidではHapticFeedbackConstants.LONG_PRESSです。触覚フィードバックがないと、ユーザーはジェスチャーが登録されたか確信が持てず、再び押して意図しないアクションを引き起こす可能性があります。
| 推奨事項 | iOS | Android |
|---|---|---|
| 認識タイムアウト | 0.5~0.65秒 | 500ms(デフォルト) |
| 触覚フィードバック | UIImpactFeedbackGenerator | HapticFeedbackConstants.LONG_PRESS |
| 視覚的フィードバック | コンテキストメニュー、ハイライト | PopupMenu、リップルアニメーション |
| アクセシビリティ | VoiceOver + Custom Actions | TalkBack + AccessibilityNodeInfo |
| 指の最大移動量 | allowableMovement = 10pt | TouchSlop(デフォルト~8dp) |
| スクロールとの競合 | cancelsTouchesInView = delayed | onInterceptTouchEvent + LongPress |
アクセシビリティ:すべてのユーザーが長押しを実行できるわけではありません(運動障害のある方、高齢のユーザー)。常にLong Pressアクションへの代替手段を提供してください — 例えば、インターフェースの「もっと見る」ボタンや、システムのアクセシビリティ機能(iOSのVoiceOver、AndroidのTalkBack)を介して。iOSでは、UIAccessibilityCustomActionを介してCustom Actionsを追加でき、VoiceOverローターから利用できます。
よくある質問
Long Pressの標準時間は両プラットフォームで0.5秒(500ms)です。iOSではminimumPressDurationを0.3~1.0秒に設定できます。AndroidではView.setOnLongClickListenerに固定の500msタイムアウトを使用します。運動能力が制限されているユーザーの場合は、タイムアウトを0.8~1.0秒に増やすことをお勧めします。
Long Pressは長押し時間(0.5秒)で認識され、3D Touchは圧力(グラム単位)で認識されます。3D TouchはiPhone 6S~XRでのみ利用可能です(ハードウェアForce Touch技術)。iOS 13以降、Appleは3D TouchをHaptic Touchに置き換えました — 触覚フィードバックを伴うLong Pressを介して動作するソフトウェアシミュレーションです。Haptic Touchはすべての最新のiPhoneとiPadで利用できます。
Long Pressとスクロールの競合は一般的な問題です。解決策:iOSのジェスチャー認識機能にdelaysTouchesBegan = trueを設定します(システムはtouchesBeganを即座に送信せず、ジェスチャー認識を待ちます)。Androidでは、Long Pressに対してfalseを返すonInterceptTouchEventを使用します。ユーザーがタイムアウト前に指を動かし始めた場合、ジェスチャーはスクロール優先でキャンセルされます。
はい、Long Pressはウェブアプリケーションでサポートされています。時間計測付きのtouchstart/touchendイベントを介して。最新のブラウザはcontextmenuイベントもサポートしており、モバイルデバイスでの長押し時に発火します。クロスブラウザ互換性のためには、hammer.jsなどのライブラリを使用するか、touchstartハンドラでsetIntervalを介してカスタム認識機能を実装してください。
iOSでは、触覚フィードバックはUIImpactFeedbackGeneratorを介して追加します。UILongPressGestureRecognizerがbegan状態に移行した瞬間にimpactOccurred()を呼び出します。軽い応答にはUIImpactFeedbackGenerator(style: .light)を、より顕著な応答には.mediumを使用します。コンテキストメニューの場合、iOSは追加コードなしでUIContextMenuInteractionを介して自動的に触覚フィードバックを追加します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。