Передача значения из SwiftUI в UIViewController с помощью UIHostingController - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть представление SwiftUI, которое состоит из TextField. Я хочу, чтобы всякий раз, когда я печатаю в TextField, он отправлял значение в элемент управления на UIKit UIViewController.

// Here is the ContentView 
class ContentViewDelegate: ObservableObject {

    var didChange = PassthroughSubject<ContentViewDelegate, Never>()

    var name: String = "" {
        didSet {
            self.didChange.send(self)
        }
    }
}

struct ContentView: View {

    @ObservedObject var delegate: ContentViewDelegate

    init(delegate: ContentViewDelegate) {
        self.delegate = delegate
    }

    var body: some View {
        VStack {
            TextField("Enter name", text: self.$delegate.name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            }.padding()
        .background(Color.green)
    }
}

Я проверял, что didChange запускается в приведенном выше коде. Но в приведенном ниже коде приемник никогда не срабатывает.

class ViewController: UIViewController {

    private var delegate = ContentViewDelegate()
    private var contentView: ContentView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.contentView = ContentView(delegate: self.delegate)

        let controller = UIHostingController(rootView: self.contentView)
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.didMove(toParent: self)

        NSLayoutConstraint.activate([
            controller.view.widthAnchor.constraint(equalToConstant: 200),
            controller.view.heightAnchor.constraint(equalToConstant: 44),
            controller.view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            controller.view.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
        ])

        _ = self.delegate.didChange.sink { delegate in
            print(delegate.name)
        }

    }

Есть идеи, почему didChange.sink не увольняют?

1 Ответ

1 голос
/ 19 апреля 2020

Если вы присваиваете издателю значение _, то оно освобождается, когда возвращается viewDidLoad. В ранних примерах от Apple показано присвоение _, и оно работало.

Необходимо убедиться, что вы сохраняете сильную ссылку на своего издателя, используя свойство:

class ViewController: UIViewController {

    private var delegate = ContentViewDelegate()
    private var contentView: ContentView!
    private var textChangePublisher: AnyCancellable?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.contentView = ContentView(delegate: self.delegate)

        let controller = UIHostingController(rootView: self.contentView)
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.didMove(toParent: self)

        NSLayoutConstraint.activate([
            controller.view.widthAnchor.constraint(equalToConstant: 200),
            controller.view.heightAnchor.constraint(equalToConstant: 44),
            controller.view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            controller.view.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
        ])

        self.textChangePublisher = self.delegate.didChange.sink { delegate in
            print(delegate.name)
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...