Skip to main content

How to create modifiers for a UIViewRepresentable struct

About 2 minSwiftSwiftUIArticle(s)bloghackingwithswift.comcrashcourseswiftswiftuixcodeappstore

How to create modifiers for a UIViewRepresentable struct 관련

SwiftUI by Example

Back to Home

How to create modifiers for a UIViewRepresentable struct | SwiftUI by Example

How to create modifiers for a UIViewRepresentable struct

Updated for Xcode 15

Wrapping a UIView in a UIViewRepresentable struct is a great way to bring existing UIKit into your SwiftUI app, and you can even add your own custom modifiers to adjust the way the view works at runtime.

To make this work, you should create private properties for all the values you want to adjust on the underlying UIView, then create methods to adjust them. Each of these methods should take a copy of your SwiftUI representable – not the underlying UIView – then adjust the private properties you created earlier to reflect the new state.

Once that’s done, SwiftUI will ensure your updateUIView() method is triggered, at which point you copy your private properties into the UIView to make sure it’s updated.

As an example, you could create a UIViewRepresentable to bridge UISearchBar into SwiftUI, but you might want some aspect of it to be customizable, such as its placeholder text. First you create the representable with an extra private property for its placeholder:

struct SearchField: UIViewRepresentable {
    @Binding var text: String

    private var placeholder = ""

    init(text: Binding<String>) {
        _text = text
    }

    func makeUIView(context: Context) -> UISearchBar {
        let searchBar = UISearchBar()
        searchBar.placeholder = placeholder
        return searchBar
    }

    // Always copy the placeholder text across on update
    func updateUIView(_ uiView: UISearchBar, context: Context) {
        uiView.text = text
        uiView.placeholder = placeholder
    }
}

Second, create a modifier on that representable to adjust the private property:

// Any modifiers to adjust your search field – copy self, adjust, then return.
extension SearchField {
    func placeholder(_ string: String) -> SearchField {
        var view = self
        view.placeholder = string
        return view
    }
}

And now you’re all set to use it. For example, this creates a SearchField view with our placeholder() modifier, but every time the button is clicked we randomize the placeholder so you can see everything in action:

struct ContentView: View {
    @State private var text = ""
    @State private var placeHolder = "Hello, world!"

    var body: some View {
        VStack {
            SearchField(text: $text)
                .placeholder(placeHolder)

            Button("Tap me") {
                // randomize the placeholder every press, to
                // prove this works
                placeHolder = UUID().uuidString
            }
        }
    }
}
Similar solutions…
How to create custom modifiers | SwiftUI by Example

How to create custom modifiers
How to stack modifiers to create more advanced effects | SwiftUI by Example

How to stack modifiers to create more advanced effects
How to make SwiftUI modifiers safer to use with @warn_unqualified_access | SwiftUI by Example

How to make SwiftUI modifiers safer to use with @warn_unqualified_access
How to detect the location of a tap inside a view | SwiftUI by Example

How to detect the location of a tap inside a view
How to wrap a custom UIView for SwiftUI | SwiftUI by Example

How to wrap a custom UIView for SwiftUI

이찬희 (MarkiiimarK)
Never Stop Learning.