Search code examples
swiftswiftuiuiviewrepresentable

Understanding UIViewRepresentable


Swift 5.0 iOS 13

Trying to understand how UIViewRepresentable works, and put together this simple example, almost there, but maybe its complete nonsense. Yes, I know there is already a tapGesture in SwiftUI, this is just a test.

Won't compile cause it says 'super.init' isn't called on all paths before returning from initialiser, which I try and set but obviously not correctly.

import SwiftUI

struct newView: UIViewRepresentable {

typealias UIViewType = UIView
var v = UIView()

func updateUIView(_ uiView: UIView, context: Context) {
  v.backgroundColor = UIColor.yellow
}


func makeUIView(context: Context) -> UIView {
  let tapGesture = UITapGestureRecognizer(target: self, action: #selector(Coordinator.handleTap(sender:)))
  v.addGestureRecognizer(tapGesture)
  return v
}

func makeCoordinator() -> newView.Coordinator {
  Coordinator(v)
}

final class Coordinator: UIView {
  private let view: UIView

init(_ view: UIView) {
    self.view = view
}

required init?(coder: NSCoder) {
  fatalError("init(coder:) has not been implemented")
}

@objc func handleTap(sender: UITapGestureRecognizer) {
    print("tap")
  }
 }

}

Solution

  • Just make your Coordinator is a NSObject, it usually plays bridge/controller/delegate/actor role, but not presentation, so should not be is-a-UIView

    final class Coordinator: NSObject {
      private let view: UIView
    
    init(_ view: UIView) {
        self.view = view
    }
    

    and one more...

    func makeUIView(context: Context) -> UIView {
      // make target a coordinator, which is already present in context !!
      let tapGesture = UITapGestureRecognizer(target: context.coordinator, 
            action: #selector(Coordinator.handleTap(sender:)))
      v.addGestureRecognizer(tapGesture)
      return v
    }