I want to scan ISBN code (book identifier) to population the view before. So I perform a segue back to the view where I come from.
And the crazy thing happened. I see my view, and the application when back to the login view (initial view), login automatically as excepted (coz already register) and stop at the tableView where you have the add button for adding a new book.
I don't understand why after my BookVC my app jump to the initial VC ?
ScanBookViewController.swift :
class ScanBookViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var book = Book()
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blackColor()
captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
guard captureSession.canAddInput(videoInput) else {
alertPopUp("Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.")
captureSession = nil
return
}
captureSession.addInput(videoInput)
let metadataOutput = AVCaptureMetadataOutput()
guard captureSession.canAddOutput(metadataOutput) else {
alertPopUp("Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.")
captureSession = nil
return
}
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code]
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func alertPopUp(title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.running == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.running == true) {
captureSession.stopRunning()
}
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
foundCode(readableObject.stringValue)
}
dismissViewControllerAnimated(true, completion: nil)
}
func foundCode(code: String) {
book.setISBN(code)
book.setTitle("Super Titre")
book.setAuthor("Gil Felot")
book.setCover(UIImage(named: "iu.png")!)
performSegueWithIdentifier("infoFinded", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "infoFinded" {
let bookVC: BookViewController = segue.destinationViewController as! BookViewController
bookVC.book = book
}
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Portrait
}
}
BookViewController.swift :
class BookViewController: UIViewController {
var book:Book!
@IBOutlet weak var bookImage: UIImageView!
@IBOutlet weak var bookTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
if book == nil {
print("test segue")
performSegueWithIdentifier("scanCode", sender: nil)
} else {
bookImage.image = book.getCover()
}
// Do any additional setup after loading the view.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Any idea, because I don't even know where to look at !
When you set up the segue did you select show (aka push) or did select modal? The standard way of handling passing data is through delegation. Create a protocol and declare a delegate in ScanBookViewController. Then set BookViewController as the delegate. Call the delegate method once you've scanned the book then pop or dismiss the scanBookViewController.
protocol ScanBookDelegate{
func didScanBook(scannedBook: Book)
}
class ScanBookViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var book = Book()
var delegate: ScanBookDelegate? // create a new delegate instance
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blackColor()
captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
guard captureSession.canAddInput(videoInput) else {
alertPopUp("Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.")
captureSession = nil
return
}
captureSession.addInput(videoInput)
let metadataOutput = AVCaptureMetadataOutput()
guard captureSession.canAddOutput(metadataOutput) else {
alertPopUp("Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.")
captureSession = nil
return
}
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code]
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func alertPopUp(title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.running == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.running == true) {
captureSession.stopRunning()
}
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
foundCode(readableObject.stringValue)
}
dismissViewControllerAnimated(true, completion: nil)
}
func foundCode(code: String) {
book.setISBN(code)
book.setTitle("Super Titre")
book.setAuthor("Gil Felot")
book.setCover(UIImage(named: "iu.png")!)
self.delegate?.didScanBook(book) //Call the delegate method
self.navigationController?.popViewControllerAnimated(true)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "infoFinded" {
let bookVC: BookViewController = segue.destinationViewController as! BookViewController
bookVC.book = book
}
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Portrait
}
}
class BookViewController: UIViewController,ScanBookDelegate {
var book:Book!
@IBOutlet weak var bookImage: UIImageView!
@IBOutlet weak var bookTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
if book == nil {
print("test segue")
performSegueWithIdentifier("scanCode", sender: nil)
} else {
bookImage.image = book.getCover()
}
// Do any additional setup after loading the view.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { //set book view controller as delegate to scan book view controller
if segue.destinationViewController is ScanBookViewController{
let scanBookViewController:ScanBookViewController = segue.destinationViewController
scanBookViewController.delegate = self
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
fun didScanBook(scannedBook:Book) //respond as delegate
{
self.book = scannedBook
}
}