Home > Software engineering >  SwiftUI ViewModifier: How to create view modifier functions without using View extensions?
SwiftUI ViewModifier: How to create view modifier functions without using View extensions?

Time:06-04

I'm building a CustomTextField View and wanting to add view modifiers.

Using the standard .modifier(CustomViewModifier) is working just fine. Now I want to build ViewModifier functions so that I can use my modifiers just like any other SwiftUI modifiers.

In my CustomTextField, I've got multiple methods like this:

func setCustomPlaceholder(placeholder: String = "Enter Text") -> some View {
        modifier(CustomTextFieldPlaceholderViewModifier(viewModel: viewModel, placeholder: placeholder))
    }

These methods work. However, I can only use one of these methods at a time.

I've read several articles and this thread. Because I don't want these modifiers available to any View, I'd like to avoid using an extension to View.

In this thread, one of the answers used an extension to Text. So I tried placing my modifier methods into an extension to my CustomTextField. However, I'm still facing the same issue. The View is only recognizing one modifier function at a time.

This is how I'm using it:

VStack {
            CustomTextField()
                .setCustomPlaceholder()
                .setBorder()
        }

If I use only one of the modifier methods at a time, it works.

How can I get the functionality I'm looking for? Do I need to build a Protocol and make my CustomTextField conform to it? Thanks for any help!

CodePudding user response:

If I use only one of the modifier methods at a time, it works

That’s because the only thing known about the result of the first view modifier is that it returns a View (of an unspecified kind).

Since you haven’t defined your view modifier on View… you can’t call it on a View.

CodePudding user response:

We can just make needed modifiers as our view member functions, which return own type to be called sequentially.

Here is a main part. Tested with Xcode 13.4 / iOS 15.5

struct CustomTextField: View {

    // ... other code

    func setCustomPlaceholder(placeholder: String = "Enter Text") -> Self {  // << here Self !!
        var tmp = self
        tmp.placeholder = placeholder
        return tmp
    }

    // ... other code
}

Complete code and demo in project

  • Related