Help us understand the problem. What is going on with this article?

長押しすると複数選択に切り替わる可変長リストの実装 (uGUI)

前提

  • unity 2018.4.1f1
  • uGUIのLayoutGroupを使って、「項目一覧」が動的に生成されるものとします。

やりたいこと (要求仕様)

  • 単数選択モード
    • 表示
      • 検索パネルが表示される。(絞り込み可能)
      • 項目毎のチェックボックスが非表示になる。
      • 複数選択メニューが非表示になる。
    • 項目をタップすると、項目が選択、決定される。
    • 項目を長押しすると、複数選択モードに切り替わる。
  • 複数選択モード
    • 表示
      • 検索パネルが非表示になる。(事前の絞り込みは可能)
      • 項目毎のチェックボックスが表示される。
        • 最初に長押しされた項目は、切り替え直後にチェック済みになる。
      • 項目数と選択数が表示される。
      • 複数選択メニューが表示される。
        • 全て選択解除、全て選択、選択項目を削除、選択項目を複製、…
    • 項目をタップすると、チェックが反転する。
    • 選択済み項目がなくなると、単数選択モードに切り替わる。
  • 共通
    • 通常のボタンと同じように、PointerUpで発動する。PointerDownのままPointerExitすると発動しない。

実現したこと

手法

  • IPointerClickHandler, IPointerDownHandler, IPointerUpHandlerを継承して、自前で挙動を組みました。
    • Toggleを試した時点で、長押し検出のために、PointerDownとPointerUpは使っていました。
    • 留意点
      • イベントは、PointerDown ⇒ PointerUp ⇒ PointerClick の順で発生します。
      • PointerDown後にPointerExitが生じた場合は、PointerUpだけが生じて、PointerClickは発生しません。
  • 概略のアルゴリズム
    • PointerDownが生じたら、時間の計測を始め、未処理のフラグを立てます。
      • PointerUpで時間計測を終了します。
    • 単数選択モード時、PointerDown後に長押し検出の閾値の時間が経過すると、モードを切り替えます。さらに、長押しされた項目を選択済みにして、フラグを処理済みに切り替えます。
    • PointerClickが生じたときは、フラグが未処理を示す場合に限り、チェックを反転します。
  • 生成コストの嵩む多数の項目を扱うために、項目の生成はコルーチンで処理していました。
    • 項目生成途中でモードが切り替わる可能性もあるので、項目毎のモードの切り替えもコルーチンで処理するようにしました。
    • 全選択は、その時点で生成済みの項目に対してのみ処理されるので、項目生成中だった場合は未選択が生じます。

挙動

  • 要求仕様を一通り満たしました。

コード

  • 汎用性がないので、上記の考え方のみで済ませたのですが、需要があるのでしたら整理して掲載します。
    • 具体的な項目内容を割愛する関係上、検索、削除、複製などの機能も割愛されます。

試みたこと

  • 最初に、Toggleをベースに実装しました。
    • Toggleの挙動とButtonの挙動をToggleに兼務させることは難なくできます。
    • しかし、PointerUpでチェックを反転するToggleの自動的な挙動と、長押しでモード切り替えた直後に最初の項目をチェック済みにする意図的な挙動が競合してしまい、要求の完全な実現はかないませんでした。
  • また、下記の実現後に、Buttonクラスを継承したクラスとして再構成することを検討したのですが、汎用性を持たせることが難しそうなので早々に断念しました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away