0

I have a UIView with 2 labels and one variable for binding like this:

var count: String? {
    get { viewCountLabel.text }
    set {
        viewCountLabel.text = newValue
        viewsTitleLabel.text = newValue == "1" ? "View" : "Views"
    }
}

and a convenience init like:

convenience init(count: String) {
    self.init()
    self.count = count
}

This view conforms to UIViewRepresentable as the following:

extension ViewCountView: UIViewRepresentable {
    typealias UIViewType = ViewCountView

    func makeUIView(context: Context) -> UIViewType {
        UIViewType(frame: .zero)
    }

    func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<UIViewType>) {}
}

This works on the target as expected.

- Question: How should I pass the count to the preview in live view?

I tried to pass the count on the initializer of the preview like the following but it doesn't work. I think I should pass the count in the form of Context somehow.

struct ViewCountView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ViewCountView(count: "0")
            ViewCountView(count: "12m")
            ViewCountView(count: "41234")
    }
}

Please Note That since I need more than 1 preview, I can't write values statically inside makeUIView or updateUIView.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278

2 Answers2

1

Add a binding var to your UIViewRepresentable:

@Binding var count: String

Then change updateUIView:

func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<UIViewType>) {
    uiView.count = count
}
Yonat
  • 4,382
  • 2
  • 28
  • 37
0

Simple wrapper struct - Works like a native:

struct <#NameOfTheWrapperView#>: UIViewRepresentable {

    typealias TheUIView = <#AnyUIView#>
    var configuration = { (view: TheUIView) in }

    func makeUIView(context: UIViewRepresentableContext<Self>) -> TheUIView { TheUIView() }
    func updateUIView(_ uiView: TheUIView, context: UIViewRepresentableContext<Self>) {
        configuration(uiView)
    }
}

Completely customizable

ResponderTextField() {
    $0.backgroundColor = .red
    $0.tintColor = .blue
}

So $0 points to the exact type and can be edited in anyway that you could in UIKit originally.


Note That I made it like a gist, so you can easily copy and paste it in your code and just need to name it and define the original UIView type you need to use.

Community
  • 1
  • 1
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • In this example, where would you put the $0.backgroundColor, etc.? – Luke Irvin Mar 18 '20 at 14:43
  • As the `configuration` argument like the example above. note that last argument is a function and can be written as a trailing closure. – Mojtaba Hosseini Mar 18 '20 at 17:11
  • So would I just use configuration per argument? For example, let's say I needed to pass a couple of values to my UIView. So configuration(uiView.value1) > new line > configuration(uiView.value2) – Luke Irvin Mar 18 '20 at 18:21