Xcode 12.4, Swift 5
SwiftUIで利用可能なDisclosureGroupについて簡単なサンプルを使って実際の動きをみていきます。公式ドキュメントでは「ディスクロージャーコントロールの状態に応じて、別のコンテンツビューを表示・非表示するビュー」とのことですが、実際の例を使ってみてみるのが理解が早そうです。
公式ドキュメント
公式ドキュメントを読み進めると、DisclosureGroupは以下の2つの要素から成り立っているようです。
- ラベル:コンテンツを識別
- コントロール:コンテンツを表示/非表示する
まずは、これら2つを最もシンプルな形で実装してみます。
最小構成
最小構成のコードは以下のようになります。
import SwiftUI
struct ContentView: View {
var body: some View {
DisclosureGroup("Label") {
Text("Text")
}
}
}

左右いっぱいに広がったエリアの左端にラベルが表示され、右端に開閉用のアイコンが表示されています。この開閉用のアイコンをタップすることで、コンテンツとして指定したTextオブジェクトが中央に表示(非表示)されます。
isExpanded Initializer追加
次に、isExpanded Initializerを使ってみることにします。これを使うことでさきほどの開閉動作を制御することが可能になります。注意しなければいけないのが、このInitializerにはBindingを用いる必要がある点です。具体的な例を使ってみていきます。
struct ContentView: View {
@State private var isExpand: Bool = true
var body: some View {
VStack {
Text("isExpanded: " + String(isExpand))
.background(Color.yellow)
DisclosureGroup("Label", isExpanded: $isExpand) {
Text("Text")
}
}
}
}

このように、Bool型の@Stateプロパティを作成し、それを参照渡し($をつけて渡す)することでDisclosureGroupの開閉に合わせてBool値であるisExpandが変化することがわかります。初期値をtrueとしていますので、開いた状態を初期状態としています。
公式サイトに近い実践的な実装
最後に公式サイトに掲載されているサンプルに近いかたちで実装した際の振る舞いをみていきます。
struct ContentView: View {
struct ToggleStates {
var oneIsOn: Bool = false
var twoIsOn: Bool = true
}
@State private var toggleStates = ToggleStates()
@State private var isExpand: Bool = true
var body: some View {
VStack {
Text("isExpanded: " + String(isExpand))
.background(Color.yellow)
DisclosureGroup("Options", isExpanded: $isExpand) {
Toggle("Option 1", isOn: $toggleStates.oneIsOn)
Toggle("Option 2", isOn: $toggleStates.twoIsOn)
}
}
}
}

Optionsを開くと、Toggleオブジェクトである、Option1とOption2が表示され、それぞれOn/Offを切り替えることができています。
まとめ
iOSアプリ開発においては、このDisclosureGroupのようにうまく開閉をもちいて限られたスペースを有効活用することで柔軟なUIが設計できそうです。同じ”Group”を冠する、GroupBoxが表示面では秀でているようにも見えるためうまく組み合わせするとよささおうです。
References


