wasim
wasim

Reputation: 708

Using Custom UIKit Classes in SwiftUI

I have created my own custom classes for UIKit objects. now i want to use same classes in SwiftUI, How can i achieve that and how much effort it will take.

Also if i want i will need to write same classes in swift UI.

example, I have custom UILable subclass WMLabel.

    class WMLabel: UILabel {
    var myproperty: String = "" {
        didSet {
            self.text = myproperty
        }
    }
}

so how can i use WMLabel in swiftUI?

I have tried ObserverableObject and UIViewRepresentable, but not able to access the properties.

Upvotes: 1

Views: 1078

Answers (2)

xTwisteDx
xTwisteDx

Reputation: 2472

Converting all of your custom classes and interfacing with them is going to be one heck of a chore if you have a few of them. You would end up using something called UIViewRepresentable which requires quite a few things, the most annoying of which called a coordinator. You'd almost be better off rewriting your classes into a SwiftUI version. Here's Apple's documentation on interfacing SwiftUI with UIKit: https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit

Here's an example of conversion of that UILabel into SwiftUI, with accessible properties.

Example Conversion

struct WMLabel: View {
    var myProperty: String
    var body: some View {
        Text(myProperty)
    }
}

Example Usage

struct Example: View {
    var body: some View {
        WMLabel(myProperty: "Hello World!")
    }
}

As you can see, there is little code involved in converting something to SwiftUI, if you start getting involved in UIViewRepresentable you have to start playing with coordinators and a bunch of other interfacing methods just to make it work. Sometimes it's required, but in most cases I'd try and avoid it.

Upvotes: 1

jnpdx
jnpdx

Reputation: 52456

You can definitely use your UIKit classes. To get basic access to the properties, you'll want to be looking at makeUIView, which occurs when the view is first created and updateUIVew.

Using your example code:

class WMLabel: UILabel {
    var myproperty: String = "" {
        didSet {
            self.text = myproperty
        }
    }
}

struct WMLabelRepresented: UIViewRepresentable {
    var text : String
    
    func makeUIView(context: Context) -> WMLabel {
        return WMLabel()
    }
    
    func updateUIView(_ uiView: WMLabel, context: Context) {
        uiView.myproperty = text
    }
}

struct ContentView : View {
    var body: some View {
        WMLabelRepresented(text: "My text")
    }
}

If there are things that can't be expressed declaratively, you'll want to look into coordinators and as you mentioned, possible an ObservableObject to communicate data imperatively to your view, but often you can find ways to express most things declaratively.

If you want an example of more complex imperative communication, here's a couple of links to another answers of mine:

Upvotes: 3

Related Questions