I want to make a custom DisclosureGroup that has the same functionality as the default DisclosureGroup but allows me to change the color text or even put an image instead of a string.
Because DisclosureGroup does not allow me to remove the blue arrow indicator on the left, and it has limitations.
The default DisclosureGroup right now is:
struct ContentView: View {
@State private var revealDetails = false
var body: some View {
DisclosureGroup("Show Terms", isExpanded: $revealDetails) {
Text("Long terms and conditions here long terms and conditions here long terms and conditions here long terms and conditions here long terms and conditions here long terms and conditions here.")
}
}
}
I want to be able to do something like this:
struct ContentView: View {
@State private var isExpanded = false
var body: some View {
CustomDisclosureGroup(isExpanded: $isExpanded, actionOnClick: {
isExpanded.toggle()
print("do something else")
}, prompt: {
HStack {
Text("this is a custom row")
.foregroundColor(Color.white)
Spacer()
Image("customArrow")
.resizable()
.frame(width: 12, height: 12)
}
.background(Color.blue)
}, expandedView: {
VStack {
Text("this is also a custom view")
Text("another one")
}
.background(Color.red)
})
}
}
While DisclosureGroup
doesn't give you the full flexibility to customize it, there are still a few things you can do:
If all you need is red arrow instead of blue, you can simply set .tint(.red)
for it.
If you need information other than text in the label, you can actually init them with:
For more sophisticated customizations, if you are running on iOS 16 or later, consider adopting DisclosureGroupStyle.
struct CustomDisclosureGroupStyle<Label: View>: DisclosureGroupStyle {
let button: Label
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.label
Spacer()
button
.rotationEffect(.degrees(configuration.isExpanded ? 90 : 0))
}
.contentShape(Rectangle())
.onTapGesture {
withAnimation {
configuration.isExpanded.toggle()
}
}
if configuration.isExpanded {
configuration.content
.padding(.leading, 30)
.disclosureGroupStyle(self)
}
}
}
struct ContentView: View {
var body: some View {
DisclosureGroup {
//...
}
.disclosureGroupStyle(CustomDisclosureGroupStyle(button: Text("ok")))
}
}