Sponsor Link
環境&対象
- macOS Big Sur 11.2.3
- Xcode 12.4
- iOS 14.4
DisclosureGroup
クリックにより、開閉するリストを作る時に使います。
Apple のドキュメントは、こちら。
多くの要素があるリストを表示する時でも、一部要素を隠すことができるので、リスト全体を俯瞰することが容易になります。
画面スナップショット
DisclosureGroup を使ったコード
以下が、上記アプリの実装コードです。
struct ContentView: View {
var body: some View {
VStack {
DisclosureGroup(
content: {
Text("Content1")
Text("Content2")
Text("Content3")
Text("Content4")
Text("Content5")
},
label: {
Text("Label")
}
)
}
.padding()
}
}
標準の DisclosureGroup の開閉方法
DisclosureGroup は、ラベル右に表示される > をクリックすることで、開閉が行われます。
ラベル自体をクリックしても、開閉は行われません。
使用ケースによっては、ラベルをクリックしても開閉できた方が便利な時があるので、その方法を説明します。
DisclosureGroup の開閉方法を追加
DisclosureGroup の init を調べてみると、isExpanded という引数ラベルを持つものがあります。
Binding<Bool> 型のこの変数を制御することで、プログラム的に DisclosureGroup の開閉を制御することができます。
# この変数を使うことで開いた状態を初期状態にすることもできます。
ラベルクリックで開閉を制御するために、この仕組みを使用します。
ラベル定義と .onTapGesture
ラベル定義を行なった時に、.onTapGesture を指定することで、そのラベルがクリックされた時の動作を指定することができます。
Text("Label")
.onTapGesture {
// tap 時の動作
}
ラベルクリックで開閉する実装
isExpand を持つ init を使った DiclosureGroup と .onTapGesture を使った Label を組み合わせたコードは、以下です。
struct ContentView: View {
// (1)
@State private var expand = false
var body: some View {
VStack {
DisclosureGroup(
// (2)
isExpanded: $expand,
content: {
Text("Content1")
Text("Content2")
Text("Content3")
Text("Content4")
Text("Content5")
},
label: {
Text("Label")
// (3)
.onTapGesture {
// (4)
expand.toggle()
}
}
)
}
.padding()
}
}
- isExpanded に使用する Bool 変数を用意します
- isExpanded を使った init で DisclosureGroup を使用します
- .onTapGesture を設定することで、Text をクリックした時の動作を設定します
- クリックされた時に、expand を toggle することで、DisclosureGroup の開閉を制御します
行全体をクリックに反応させる方法
ここまでの実装でテキストをクリックしても、DisclosureGroup が開閉するようになりました。
便利にはなったのですが、テキストが短い時にクリックが難しいかもしれません。
以下のようにすると、行全体がクリック対象となります。
Text("Label")
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(Rectangle())
.onTapGesture {
expand.toggle()
}
.frame で行をいっぱいまで横に広げてつつ 左寄せで表示するようにしています。
その後、.contentShape で矩形を指定することで行全体がクリック対象となります。
まとめ:DisclosureGroup の開閉を行のどこをクリックしてもできるようにする方法
- isExpanded を指定できる init で DisclosureGroup を設定する
- .onTapGesture で isExpanded を制御することで、クリックによる開閉制御を行う
- .frame と .contentShape を組み合わせることで、行のどこをクリックしても反応できるようにする
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link