I'm working on building out some forms where some of the fields are drop-downs that push on a list of options for the user to make their selection. In some cases, the user may not be allowed to edit a particular field or even the entire form based on their permissions or the state of the object the form represents. Visually, I would prefer that the disclosure indicator not be shown when the user isn't allowed to edit a drop down field.
A naive implementation might be:
if self.canEdit {
NavigationLink {
OptionList(...)
} label: {
DropDownField(...)
}
} else {
DropDownField(...)
}
That can get pretty messy though, especially on a form with a lot of drop down fields. It occurred to me that I could accomplish the same thing using a ViewModifier and an extension on View like this:
extension View {
func navigationLink<Destination: View>(when condition: Bool, @ViewBuilder destination: @escaping () -> Destination) -> some View {
modifier(ConditionalNavigationLink(when: condition, destination: destination))
}
}
struct ConditionalNavigationLink<Destination: View>: ViewModifier {
let condition: Bool
let destination: () -> Destination
init(when condition: Bool, @ViewBuilder destination: @escaping () -> Destination) {
self.condition = condition
self.destination = destination
}
func body(content: Content) -> some View {
if condition {
NavigationLink(destination: self.destination, label: { content })
} else {
content
}
}
}
Which would allow me to simplify my previous implementation to:
DropDownField(...)
.navigationLink(when: self.canEdit) {
OptionList(...)
}
Does this seem like a reasonable solution? Are there any drawbacks I'm not thinking of or a better way of accomplishing this?