I'm building a QR code reader into my app, so far I have it open as a sheet and close when a qr/barcode is detected. The reader part of the app uses UIKit, I have the file QRCodeScan.swift which is the UIViewControllerRepresentable, the qr scanner returns the value of the code that it has found into the coordinator in this file. I can't seem to find any way to get the found code out of the coordinator into the original view.
This is the file QRCodeScan.
struct QRCodeScan: UIViewControllerRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> ScannerViewController {
let vc = ScannerViewController()
vc.delegate = context.coordinator
return vc
}
func updateUIViewController(_ vc: ScannerViewController, context: Context) {
}
class Coordinator: NSObject, QRCodeScannerDelegate {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
func codeDidFind(_ foundCode: String) {
print(foundCode)
/*this is where the code comes to, need to return it from here */
presentationMode.wrappedValue.dismiss()
}
var parent: QRCodeScan
init(_ parent: QRCodeScan) {
self.parent = parent
}
}
}
This is a cropped down version of the ContentView that calls the qr reader , this is where I need to get the found code back into
struct ContentView: View {
@State var presentQRScanner = false
var body: some View {
NavigationView{
Form{
Section(header: Text("Info")){
Button("Scan Barcode"){
self.presentQRScanner = true
}
.sheet(isPresented: $presentQRScanner){QRCodeScan()}
}
}
.navigationBarTitle(Text("New"), displayMode: .large)
.navigationBarItems(trailing: Button("Save"){
print("Button Pressed")
})
}
}
}
I've hit a total roadblock here, I can't find any resources that allow me to pass the data back from the coordinator, maybe I'm implementing something wrong but I can't seem to adapt any other solutions to fit
Any help is much appreciated.
Thanks
However, with SwiftUI released roughly two and a half years ago and maturing ever since, the question arises of how to use the Coordinator pattern with SwiftUI. It turns out that it’s not as easy as replacing all the UIKit views (and view controllers) with their SwiftUI equivalents.
Since all Views in SwiftUI are struct, we can add a Writer property to SecondView without providing an initial value. You will use this property to receive the data from ContentView.
Use SwiftUI’s data flow to access what you need in the Core Data framework. Define and create new model objects using Core Data. Use Fetch Requests to retrieve objects from disk. So buckle up and learn more about Core Data’s capabilities and how it works!
In this article, we will study all the available options, and look at some best practices regarding when you should use which mechanism. The most common way of transferring data in SwiftUI is from a parent view to its direct child. The parent just instantiates the child and passes data to its initializer.
You may have already solved this, but the solution is to use an @State variable in your ContentView linked to an @Binding variable in your QRCodeScan Struct and the Coordinator Class.
Check out this answer: Accessing MKMapView elements as UIViewRepresentable in the main (ContentView) SwiftUI view
Something like this should do the trick, but I suggest reading over the more detailed answer I linked:
struct QRCodeScan: UIViewControllerRepresentable {
@Binding var code: String
func makeCoordinator() -> Coordinator {
return Coordinator(code: $code)
}
func makeUIViewController(context: Context) -> ScannerViewController {
let vc = ScannerViewController()
vc.delegate = context.coordinator
return vc
}
func updateUIViewController(_ vc: ScannerViewController, context: Context) {
}
class Coordinator: NSObject, QRCodeScannerDelegate {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Binding var code: String
init(code: Binding<String>) {
_code = code
}
func codeDidFind(_ foundCode: String) {
print(foundCode)
/*this is where the code comes to, need to return it from here */
self.code = foundCode
presentationMode.wrappedValue.dismiss()
}
var parent: QRCodeScan
init(_ parent: QRCodeScan) {
self.parent = parent
}
}
}
In your ContentView, create @State var code, then you can call QRCodeScan(code: $code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With