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

iOSでちょっと多めのツールアイテムに対応可能なツール選択 UI Component

SegmentedToolControl

お絵描き系のアプリや画像編集系のアプリを作成する時、多くのツールを用意したい場合があったりします。そんなツールを選択させたい場合に、UISegmentedControl を使いたいと思うことがあるかもしれません。ただ、UISegmentedControl はアイテムを横に並べるのは得意ですが、アイテムを縦に並べる事は正攻法ではできません。よって画面の横側に縦に並べたようなデザインにしようと思うと困ってしまいます。

また、画面のサイズの都合もあるので、アイテムの数が増えると、ずらずらと一列に並べるというわけにはいきません。アイテムをある程度グループに分類して、多段階的に選択できれば、画面の表示領域を節約できます。

今回はこんな目的の為に、必要に迫られて書いた SegmentedItemControl を公開できるように少々手を入れたので、紹介したいと思います。

SegmentedToolControl は GitHub より取得可能です。
https://github.com/codelynx/SegmentedToolControl

SegmentedToolControl は名前にControl とついていますが、UIControl のサブクラスではなくUIViewのサブクラスです。SegmentedToolControlは、縦、横向きに配置が可能で、複数のアイテムをカテゴリー毎などにグループ化して一つのアイコンとして配置可能です。そして、それらのカテゴリーを代表するアイコンを一列に配置し、UI のコンポーネントとして利用できます。

以下に利用例の画像を紹介します。画面の右端にアイテムを縦並びに並べて、カテゴリで長押しすると同カテゴリのサブアイテムがポップします。

実際に選択状態にあるツールは常に一つです。ユーザーはまずカテゴリーアイコンを長押しするとサブアイテムのアイコンがポップアップします。ポップアップする向きはプロパティで指定する事ができます。目的のサブアイテムへ指を動かして離すと、そのアイテムを選択した事になります。

選択状態は delegate に通知されるので、クライアント側のコードはどのアイテムが選択されたか知る事ができます。

現段階では、Interface Builder から様々な設定ができるわけではなく、コーディングによるコンフィグレーションの設定が必要になります。

主なクラス

SegmentedItem

SegmentedToolControlで選択可能なアイテムです。

SegmentedItem(identifier: "paintbrush", image: UIImage(systemName: "paintbrush")

SegmentedCategoryItem

SegmentedItem をカテゴリーまたはグループ別にまとめて表示上一つのアイテムのように表示します。

SegmentedCategoryItem(items: [
   SegmentedItem(identifier: "hammer", image: UIImage(systemName: "hammer"),
   SegmentedItem(identifier: "wrench", image: UIImage(systemName: "wrench")
])

SegmentedToolControl

SegmentedToolControl の本丸です。コードでのセットアップの例です。

let toolControl: SegmentedToolControl = ...
toolControl.itemSize = Self.itemSize
toolControl.orientation = .vertical
toolControl.direction = .right
toolControl.delegate = self
toolControl.segmentedCategoryItems = [
    SegmentedCategoryItem(items: [
        SegmentedItem(identifier: "hammer", image: UIImage(named: "hammer"),
        SegmentedItem(identifier: "wrench", image: UIImage(named: "wrench")
    ]),
    SegmentedCategoryItem(items: [
        SegmentedItem(identifier: "hare", image: UIImage(named: "hare"),
        SegmentedItem(identifier: "tortoise", image: UIImage(named: "tortoise")
    ])
]

orientation プロパティはアイテムの並びが水平か垂直かを指定します。
direction プロパティはサブアイテムがポップする際の方向を指定します。

そしてデリゲートを実装すれば、アイテムが選ばれた際に呼ばれます。

    func segmentedToolControl(_ control: SegmentedToolControl, didSelectItem: SegmentedItem) {
        switch control.selectedItem.identifier {
        case "hammer": // ...
        case "wrench": // ...
        }
    }

サンプルプロジェクトより、orientation と direction のそれぞれを指定したサンプルのスクリーンショットを貼っておきます。

以下に執筆時点での環境を記します。

Xcode Version 11.2.1 (11B500)
$ swift --version
Apple Swift version 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)
Target: x86_64-apple-darwin19.0.0
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
No 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
ユーザーは見つかりませんでした