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