Reputation: 11337
@State var modifierEnabled : Bool
struct BlankModifier: ViewModifier {
func body(content: Content) -> some View {
content
}
}
extension View {
func TestModifierView() -> some View{
return self.modifier(BlankModifier())
}
}
How to apply TestModifierView
only in case of modifierEnabled == true
?
Upvotes: 4
Views: 2536
Reputation: 11337
@available(OSX 11.0, *)
public extension View {
@ViewBuilder
func `if`<Content: View>(_ condition: Bool, content: (Self) -> Content) -> some View {
if condition {
content(self)
} else {
self
}
}
}
@available(OSX 11.0, *)
public extension View {
@ViewBuilder
func `if`<TrueContent: View, FalseContent: View>(_ condition: Bool, ifTrue trueContent: (Self) -> TrueContent, else falseContent: (Self) -> FalseContent) -> some View {
if condition {
trueContent(self)
} else {
falseContent(self)
}
}
}
usage example ( one modifier ) :
Text("some Text")
.if(modifierEnabled) { $0.foregroundColor(.Red) }
usage example2 (two modifier chains related to condition) :
Text("some Text")
.if(modifierEnabled) { $0.foregroundColor(.red) }
else: { $0.foregroundColor(.blue).background(Color.green) }
Important thing that this modifier can be reason of some indentity issues. (later you will understand this)
So in some cases better to use standard if
construction
Upvotes: 11
Reputation: 5125
I like the solution without type erasers. It looks strict and elegant.
public extension View {
@ViewBuilder
func modify<TrueContent: View, FalseContent: View>(_ condition: Bool, ifTrue modificationForTrue: (Self) -> TrueContent, ifFalse modificationForFalse: (Self) -> FalseContent) -> some View {
if condition {
modificationForTrue(self)
} else {
modificationForFalse(self)
}
}
}
Usage
HStack {
...
}
.modify(modifierEnabled) { v in
v.font(.title)
} ifFalse: {
$0.background(Color.red) // even shorter
}
If you only plan to apply a modifier (or a chain of modifiers) consider this:
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public extension View {
@ViewBuilder func modifier<VM1: ViewModifier, VM2: ViewModifier>(_ condition: @autoclosure () -> Bool, applyIfTrue: VM1, applyIfFalse: VM2
) -> some View {
if condition() {
self.modifier(applyIfTrue)
} else {
self.modifier(applyIfFalse)
}
}
}
Usage is almost as simple as with regular .modifier
.
...
Form {
HStack {
...
}
.modifier(modifierEnabled, applyIfTrue: CornerRotateModifier(amount: 8, anchor: .bottomLeading), applyIfFalse: EmptyModifier())
...
You can omit applyIfFalse
part for conciseness and just return self.erase()
if condition is false.
Upvotes: 0