Как передать строку из UIViewController обратно в SwiftUI View (iOS) - PullRequest
1 голос
/ 03 ноября 2019

Извините за то, что кажется простым вопросом / ответом, но я не смог ни разобраться, ни найти решение. Мне нужно использовать AVFoundation для приложения, которое я пишу. В основном, сканирование штрих-кода и отправка этой информации обратно в другой ViewController. Это было довольно легко / просто с Swift и UIKit, и у меня это работало.

Теперь я запускаю ViewController, используя лист (передавая переменную @State, чтобы я мог закрыть лист позже):

.sheet(isPresented: $isShowingCamera, content: {
    ScanItem(isPresented: self.$isShowingCamera)
})

ScanItem - это UIViewRepresentable Вот функции в ScanItem:

func makeCoordinator() -> ScanItem.Coordinator {
    return Coordinator(self)
}

public typealias UIViewControllerType = ScanBarcodeViewController

func makeUIViewController(context: UIViewControllerRepresentableContext<ScanItem>) -> ScanBarcodeViewController {
    return ScanBarcodeViewController()
}

func updateViewController(_ uiViewController: ScanBarcodeViewController, context: UIViewControllerRepresentableContext<ScanItem>) {
}

Внутри у меня есть необходимые методы, и он отображает другой созданный мной UIViewController, который использует AVFoundation для отображения камеры и просмотрадля штрих-кода. Я считаю, что мне нужно прогрессировать - заставить координатора обрабатывать AVCaptureMetaData. У меня есть координатор, как показано ниже:

class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
    let parent: ScanItem
    init(_ parent: ScanItem) {
        self.parent = parent
    }

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    let metaDataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    if metaDataObj.stringValue != nil {
        self.parent.$metadata = metadataObj.stringValue
        self.parent.$isPresented = false
    }
}

Я думаю, что я на правильном пути. Эта функция обычно вызывается в расширении viewcontroller как AVCaptureMetadataOutputObjectsDelegate. Я думаю, что мне нужно установить координатор в качестве делегата, вызвать функцию, установить некоторую привязываемую переменную (@Bindable var metadata: String) и обработать ее в представлении SwiftUI.

Мои текущие ошибки: ScanBarcodeViewController (мой viewcontoller)загрузить камеру) не может быть построено, потому что у него нет доступных инициализаторов, который идет вместе с классом ScanBarcodeViewController не имеет инициализаторов self.parent. $ metaData = metaDataObj.stringValue -> не может присвоить значение типа String типу Binding - fixed self.parent. $ isPresented = false -> не может присвоить значение типа Bool типу Binding - исправлено

Заранее спасибо. Если вам нужно, чтобы я опубликовал больше кода, я был бы рад сделать это.

1 Ответ

0 голосов
/ 04 ноября 2019

Вместо передачи себя в Координаторе (который является структурой, поэтому копируется), т.е.

Coordinator(self)

использует привязку к вашей модели напрямую, так что вы можете изменить ее, например, как

func makeCoordinator() -> Coordinator {
    return Coordinator(data: $metadata)
}

и в Координаторе ..

final class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
    var data: Binding<String>

...

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    let metaDataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    if metaDataObj.stringValue != nil {
        ...
        data.wrappedValue = metadataObj.stringValue
        ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...