Issues presenting UIViewController in Xcode 11, SwiftUI - ios

I have a QR Code scanner, which is embedded in a UIViewController. I've been looking around at other posts and blogs but all are single page apps which present the UIViewController as the primary one on launch of the application. I just need it to open inside of a button action, and for some reason I can't get it to present the scanner correctly?
Here's the QR Scanner Code:
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed()
return
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
and here's my (very simplistic) attempt to have it open upon pressing a button:
struct ScanView: View{
var body: some View{
VStack {
Button(action: {
ScannerViewController()
}) {
Text("Scan QR Code").foregroundColor(Color.white).padding()
}.frame(width: 150)
.background(Color.blue)
.cornerRadius(25)
}
}
}
I've tried looking at a few other StackOverflow posts regarding these types of issues, but some are either using deprecated ways of scanning qr codes or are otherwise irrelevant to the issue I'm facing.
I'm sure it's something fairly simple but my Swift/Xcode expertise mostly regards design and styling with basic knowledge of API calls, but I don't necessarily understand how the different view hierarchies and calling methods work.
I would like to fix this issue, of course, but I'd also like to know what the issue was so that I can know for next time.

We can not directly call UIViewController in SwiftUI.
Need UIViewControllerRepresentable to present a UIViewController.
You can read about it here:
https://developer.apple.com/documentation/swiftui/uiviewcontrollerrepresentable
https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit
Try this, it is working and I can see the content through camera :
import SwiftUI
import UIKit
import AVFoundation
struct ScannerView: UIViewControllerRepresentable {
typealias UIViewControllerType = ScannerViewController
func updateUIViewController(_ uiViewController: ScannerViewController, context: Context) {
print("update")
}
func makeUIViewController(context: Context) -> ScannerViewController {
return ScannerViewController()
}
}
and in you struct ScanView:
struct ContentView: View {
#State private var showingScanner = false
var body: some View {
VStack {
Button(action: {
self.showingScanner = true
}) {
Text("Scan QR Code").foregroundColor(Color.white).padding()
}.frame(width: 150)
.background(Color.blue)
.cornerRadius(25)
}.sheet(isPresented: $showingScanner) {
ScannerView()
}
}
}
The camera view, I have dragged the camera view below so that you can see the button screen in the background:
P.S. Don't forget to add Privacy - Camera Usage Description in info.plist

I'm not an xCode expert. Much less a SwiftUI expert. But it looks like you're trying to navigate from a SwiftUI view to a UIKit view. That threw me off for a minute.
Anyways, you're going to want to wrap your button in a NavigationView.
https://www.hackingwithswift.com/articles/216/complete-guide-to-navigationview-in-swiftui

Related

Has .addSublayer() changed in Swift 5.5?

I'm trying to use a Swift class from hackingswift.com that reads QR codes. This code has apparently been used in the past by posters to this forum, but it doesn't work now in Swift 5.5. I get an error 'expression failed to parse, unknown error' on the line
view.layer.addSublayer(previewLayer)
in the following. Any help would be appreciated.
//: A UIKit based Playground for presenting user interface
import AVFoundation
import UIKit
import PlaygroundSupport
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed()
return
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = ScannerViewController()
This is an annoying bug in playgrounds. Leaving aside for a moment that there is no capture device available in playgrounds or the simulator, so none of this will work anyway, the fix is to treat view as an optional:
view?.layer.addSublayer(previewLayer)
I have no idea why this is the case, and nor do some other people
.addSublayer is working as expected.
You can try out the sample code below in the playground for testing.
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view.backgroundColor = .cyan
let layer = CALayer()
layer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
layer.position = CGPoint(x: 200/2, y: 200/2)
layer.backgroundColor = UIColor.magenta.cgColor
layer.borderWidth = 5
layer.borderColor = UIColor.black.cgColor
view.layer.addSublayer(layer)
PlaygroundPage.current.liveView = view
I rapidly tried the sample code you provided in Playgrounds and AVCaptureDevice.default(for: .video) seems to fail.

Scanning barcodes one at a time in SwiftUI

I've used this guide to create my scanner:
I first run QRCodeScan() from content view with an overlay:
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
QRCodeScan()
ScannerOverlayView()
}
}
}
QRCodeScan:
import SwiftUI
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 {
#State var barcode = ""
func codeDidFind(_ code: String) {
barcode = code
FoundItemSheet(barcode: self.$barcode) //This creates a sheet at the bottom of the screen, saying if a product was found with the barcode
}
var parent: QRCodeScan
init(_ parent: QRCodeScan) {
self.parent = parent
}
}
}
ScannerViewController:
protocol QRCodeScannerDelegate {
func codeDidFind(_ code: String)
}
import AVFoundation
import UIKit
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
var delegate: QRCodeScannerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed()
return
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.ean13, .ean8, .qr]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
self.delegate?.codeDidFind(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
It scans a barcode successfully, but that picture remains on the screen. I want a barcode to be scanned; the code be passed do FoundItemSheet(), then open the scanner again.
I've tried running QRCodeScan() inside of codeDidFind() and calling the ScannerViewController again.

Swift 4 QRCode Scanning [duplicate]

This question already has answers here:
Barcode on swift 4
(4 answers)
Closed 5 years ago.
That's the code I'm trying to scan QRCodes
import AVFoundation
import UIKit
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed()
return
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
Found it here.
But it doesn't work, everything is set correctly, I get the ViewController loaded and the captureSession running, but when I point to a QRcode nothing happens, captureOutput() is never called.
Please check your delegate method is wrong. Its should be like below :
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

Adding objects over camera view in barcode scanner app (Swift 3)

On my storyboard, I have a view controller, that has the following class associated with it:
import AVFoundation
import UIKit
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed();
return;
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeCode39Code]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
previewLayer.frame = view.layer.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
view.layer.addSublayer(previewLayer);
captureSession.startRunning();
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning();
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning();
}
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
captureSession.stopRunning()
let initialView: PLLogViewController = presentingViewController as! PLLogViewController
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: readableObject.stringValue);
initialView.setResults(code: readableObject.stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
This code basically initiates a camera view that acts as a barcode scanner. If you point your device at a barcode, it'll detect the barcode, and push the results to a text field.
This all works great. My question is - I would like to have some other elements showing on the screen. Right now, my entire screen is being overtaken by the camera, and so if you access this view, you either HAVE to scan a barcode, or you have to shut down the app.
I attempted to add other elements in the view just by dragging them from the object library, however, the camera seems to overlay those items, making them inaccessible.
There are two elements that I would like to add over top of the camera view. The first is an image, that looks like a "bracket" to give some indication of where the user should "fit" the barcode they are scanning.
The second is a button that allows the user to cancel out of the camera view.
So ultimately, my question is simply, how can I add elements over top of a camera view that is being initialized programmatically?
add a view in you view controller were you want your video preview to appear then simply add the preview layer to that layer instead of the whole view.
Like so:
// Initialize the video preview layer and add it as a sublayer to your views layer.
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer?.frame = /*your views name here i e qrView*/.layer.bounds
/*your views name here i e qrView*/.layer.addSublayer(videoPreviewLayer!)
// instead of
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
previewLayer.frame = view.layer.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
view.layer.addSublayer(previewLayer);

Disable rotation only for AVCaptureVideoPreviewLayer

I have a UITabBarController which has 4 items tabs. One of them is an AvCaptureVideoPreviewLayer (is a barcode scanner). What I would like to do is to disable autorotate only for AVCaptureVideoPreviewLayer (like iOS camera app) but not for the item bar which would rotate with the screen. It is a bit difficult situation because I think that the UITabBarConrtoller doesn't allow you easily to disable rotation.
The code for my camera view is:
import UIKit
import AVFoundation
class ScannerViewController: UIViewController,
// MARK: Properties
/// Manages the data flow from the capture stage through our input devices.
var captureSession: AVCaptureSession!
/// Dispays the data as captured from our input device.
var previewLayer: AVCaptureVideoPreviewLayer!
// MARK: Methods
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blackColor()
self.captureSession = AVCaptureSession()
// This object represents a physical capture device and the properties associated with that device
let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
// Is useful for capturing the data from the input device
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
// TODO: maybe show an alert
return
}
if (self.captureSession.canAddInput(videoInput)) {
self.captureSession.addInput(videoInput)
} else {
failed();
return;
}
let metadataOutput = AVCaptureMetadataOutput()
if (self.captureSession.canAddOutput(metadataOutput)) {
self.captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code]
} else {
failed()
return
}
// Adds the preview layer to display the captured data. Sets the videoGravity to AspectFill so that it covers the full screen
self.previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession);
self.previewLayer.frame = self.view.layer.bounds;
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.view.layer.addSublayer(previewLayer);
self.captureSession.startRunning();
}
override func viewDidLayoutSubviews() {
self.previewLayer?.frame = self.view.layer.bounds;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if (self.captureSession.running == false) {
self.captureSession.startRunning();
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if (self.captureSession.running == true) {
self.captureSession.stopRunning();
}
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
self.captureSession = nil
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
self.captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
foundCode(readableObject.stringValue);
}
}
/// Completes some tasks when a barcode is found.
///
/// - parameter code: The the barcode found.
func foundCode(code: String) {
}
}
I'm not 100% sure if I understand it correctly. But what you could do is:
1 - Subclass your UITabBarController and override shouldAutorotate with something like this:
override var shouldAutorotate: Bool {
guard let viewController = tabBarController?.selectedViewController else { return false }
return viewController.shouldAutorotate
}
This means that the selected UIViewController will define if it should autorotate.
2 - Now that the UITabBarController will ask its ViewControllers if it should autorotate, you have to override shouldAutorotate in every controller as well.
And that's it!
Sorry if I misunderstood your question. If you provide more information it would help.
Take care :)

Resources