4

I have written a custom view modifier:

import SwiftUI

public struct Watermark: ViewModifier {
    
    // watermark text
    public var text: String     = " watermark"
    public var align: Alignment = .bottomTrailing
    
    // body
    public func body(content: Content) -> some View {
        
        let textView = Text(text)
            .font(.caption)
            .foregroundColor(.white)
            .padding(8)
            .background(Color.black).padding(5)
            .opacity(0.6)
        
        return content.overlay(textView, alignment: align)
    }
}

extension View {
    // use view modifier
    public func watermark(
        _ text : String    = " watermark", 
        _ align: Alignment = .bottomTrailing
    ) -> some View {
        self.modifier(Watermark(text: text, align: align))
    }
}

and a View extension:

import SwiftUI

extension View {
    // modify the view directly
    public func watermark2(
        _ text : String    = " watermark", 
        _ align: Alignment = .bottomTrailing
    ) -> some View 
    {
        let textView = Text(text)
            .font(.caption)
            .foregroundColor(.white)
            .padding(8)
            .background(Color.black).padding(5)
            .opacity(0.6)
        
        return self.overlay(textView, alignment: align)
    }
}

and the following code uses the view modifier and the View extension above:

import SwiftUI
import PlaygroundSupport

// content view
struct ContentView: View {
    var body: some View {
        VStack {
            // use view modifier
            Color.gray.watermark()
            Color.gray.watermark("hello", .topTrailing)
            // use view extension
            Color.gray.watermark2("hi", .center)
            Color.gray.watermark2("example", .topLeading)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

the result looks like this:

playground result

My question is: if we can do the job by simply using a View extension, why bother using a view modifier? What's the benefit of using it?

lochiwei
  • 1,240
  • 9
  • 16
  • 2
    in extension function you can wrap existed modifiers, but in ViewModifer you can create your own with stored properties, including states and other dynamic properties, also make it animatable, etc. – Asperi Sep 10 '20 at 14:52
  • @Asperi I'm not quite sure, but we can achieve the same thing using a method with parameters in a `View` extension, am I right? – lochiwei Sep 11 '20 at 04:43
  • @Asperi Maybe you are right, we can't use property wrappers such as `@State`, `@Binding` etc in an extension function, right? – lochiwei Sep 11 '20 at 12:32
  • This thread appears to answer the question: https://stackoverflow.com/q/57411656/1816667 – Marcy Feb 22 '23 at 00:00

0 Answers0