Пользовательский UIViewController с UIViewcontrollerRepresentable, который имеет UITextView, который дает сбой или равен нулю при вызове в SwiftUI

Я сделал обычай UIViewController называется ViewControllerA и хочу иметь возможность его использовать, поэтому я сделал UIViewControllerRepresentable называется ViewControllerARepresentable как показано ниже, проблема в том, что когда я звоню ViewControllerARepresentable в моем представлении SwiftUI и передать значение для stringToUpdateTextView, то ViewControllerA говорит htmlTextView(UITextView) в ViewControllerA является nil и я не знаю почему.

ViewControllerARepresentable(stringToUpdateTextView: "<html>Send some Html Text as string here</html>")

ViewControllerARepresentable

public struct ViewControllerARepresentable: UIViewControllerRepresentable {
  var stringToUpdateTextView: String

  public func makeUIViewController(context: Context) -> ViewControllerA {
    let viewcontrollerA = ViewControllerA(testString: testingString)

    return viewcontrollerA
  }

  public func updateUIViewController(_ uiViewController: ViewControllerA, context: Context) {}
}

ViewControllerA

open class ViewControllerA: UIViewController {

  public var stringToUpdateTextView: String

  override open func viewDidLoad() {
    super.viewDidLoad()

htmlTextView.text = stringToUpdateTextView
  }

  @IBOutlet weak var htmlTextView: UITextView!

  public init(testString: String) {
    self.testString = testString
    super.init(nibName: nil, bundle: nil)
  }

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

Авария происходит в htmlTextView.text = stringToUpdateTextViewговоря, что htmlTextView.text равен нулю, хотя это IBOutlet. Любое изменение, внесенное в htmlTextView, например цвет фона и т. Д., Также вызывает сбой при вызове в viewDidAppear или viewDidLoad.

1 ответ

Решение

При создании экземпляра вашего контроллера представления в makeUIViewController, розетки еще не инициализированы.

Следующий код загружает ваш контроллер представления из раскадровки и обновляет свойства в updateUIViewController:

ViewController.swift

import UIKit
import SwiftUI

class ViewController: UIViewController {

  @IBOutlet weak var htmlTextView: UITextView!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

}

struct ViewControllerWrapper: UIViewControllerRepresentable {
  typealias UIViewControllerType = ViewController

  @Binding var text: String

  func makeUIViewController(context: Context) -> ViewController {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    guard let viewController =  storyboard.instantiateViewController(
      identifier: "ViewController") as? ViewController else {
        fatalError("Cannot load from storyboard")
    }
    return viewController
  }

  func updateUIViewController(_ uiViewController: ViewController, context: Context) {
    uiViewController.htmlTextView.text = text
  }

}


struct ViewControllerPreview: PreviewProvider {
  static var previews: some View {
    ViewControllerWrapper(text: .constant("hello world!"))
  }
}

SwiftUIView.swift

struct SwiftUIView: View {
  @State var text = "Text"
  var body: some View {
    HStack {
      TextField("Text:", text: $text)
      ViewControllerWrapper(text: $text)
    }
  }
}
Другие вопросы по тегам