2016-07-08 4 views
0

책에 관한 앱을 만들고 있습니다. 응용 프로그램에서 , 내가 2 개 클래스팝업보기 컨트롤러 후 데이터를 신속하게 전달하는 방법

views

있다 ISBN (바코드)를 얻어서 응용 프로그램 자동 충전 도서 정보를 만들고 싶어. 하나는 'UploadMain'이고 다른 하나는 'ScanView'입니다.

스캔으로 ISBN을 얻을 수 있는데 이지만 ScanView에서 UploadMain으로 데이터를 전달하는 데 문제가 있습니다.

은 ScanView에서 내가 무슨 문제가 내 코드를 모르는 UploadMain 클래스

override func viewDidLoad(){ 
    super.viewDidLoad() 
    ISBN.delegate = self 

} 

override func viewWillAppear(animated: Bool){ 
    ISBN.text = ISBNstring 
} 

에 대한

if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { 
    UploadVC.ISBNstring = self.detectionString! 
} 

아래 코드처럼 바인딩 옵션 사용했다.

전체 코드 의 UploadMain

import UIKit 
import Foundation 

class UploadMain: UIViewController,UITextFieldDelegate { 


var ISBNstring: String = "" 
var TitleString: String = "" 
var AuthorString: String = "" 
var PubString: String = "" 
var PriceSting: String = "" 

@IBOutlet weak var ISBN: UITextField! 

@IBOutlet weak var bookTitle: UITextField! 

@IBOutlet weak var bookAuthor: UITextField! 

@IBOutlet weak var bookPub: UITextField! 

@IBOutlet weak var bookPrice: UITextField! 



override func viewDidLoad(){ 
    super.viewDidLoad() 
    ISBN.delegate = self 
} 

override func viewWillAppear(animated: Bool){ 
    ISBN.text = ISBNstring 
} 



@IBAction func Upload(sender: AnyObject) { 
    dismissViewControllerAnimated(true, completion: nil) 
} 
} 

ScanView 클래스는 나에게

import UIKit 
import AVFoundation 
import Foundation 


class ScanView : UIViewController, AVCaptureMetadataOutputObjectsDelegate { 



let session   : AVCaptureSession = AVCaptureSession() 
var previewLayer : AVCaptureVideoPreviewLayer! 
var detectionString : String! 
let apiKey : String = "---------dddddd" 


override func viewDidLoad() { 
    super.viewDidLoad() 

    // For the sake of discussion this is the camera 
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

    // Create a nilable NSError to hand off to the next method. 
    // Make sure to use the "var" keyword and not "let" 
    var error : NSError? = nil 
    var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
    do { 
     input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
    } catch let myJSONError { 
     print(myJSONError) 
    } 

    // If our input is not nil then add it to the session, otherwise we're kind of done! 
    if input != AVCaptureDeviceInput() { 
     session.addInput(input) 
    } 
    else { 
     // This is fine for a demo, do something real with this in your app. :) 
     print(error) 
    } 

    let output = AVCaptureMetadataOutput() 
    output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
    session.addOutput(output) 
    output.metadataObjectTypes = output.availableMetadataObjectTypes 


    previewLayer = AVCaptureVideoPreviewLayer(session: session) 
    previewLayer.frame = self.view.bounds 
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
    self.view.layer.addSublayer(previewLayer) 

    // Start the scanner. You'll have to end it yourself later. 
    session.startRunning() 

} 



// This is called when we find a known barcode type with the camera. 
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

    var highlightViewRect = CGRectZero 
    var barCodeObject : AVMetadataObject! 
    let barCodeTypes = [AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code] 


    // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
    for metadata in metadataObjects { 

     for barcodeType in barCodeTypes { 

      if metadata.type == barcodeType { 
       barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

       highlightViewRect = barCodeObject.bounds 

       detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

       self.session.stopRunning() 

       self.alert(detectionString) 

       // Daum Book API 호출 
       let apiURI = NSURL(string: "https://apis.daum.net/search/book?apikey=\(apiKey)&q=\(detectionString)&searchType=isbn&output=json") 

       let apidata : NSData? = NSData(contentsOfURL: apiURI!) 

       NSLog("API Result = %@", NSString(data: apidata!, encoding: NSUTF8StringEncoding)!) 

       **if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { 
        UploadVC.ISBNstring = self.detectionString! 
       }** 

       break 
      } 

     } 
    } 

    print(detectionString) 
    self.navigationController?.popViewControllerAnimated(true) 

} 



func alert(Code: String){ 
    let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

    // for alert add .Alert instead of .Action Sheet 
    // start copy 
    let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 
     { 
      (alertAction:UIAlertAction!) in 

      // action when pressed 
      self.session.startRunning() 
    }) 


    actionSheet.addAction(firstAlertAction) 

} 

} 
+0

'스토리 보드'에서 ScanView의 'segue'는 'button'으로 연결되어 있습니다. 맞습니까? –

답변

0

를 데이터

내가 당신을 위해 그것을 밖으로 쓸 수 있지만, 프로그래머를 보낼 것입니다 새 창 UploadMain은 창 계층에서 사용할 수 없기 때문에 데이터를 UploadMain에서 사용할 수 없습니다. 문제를 해결하려면 하나를 만들고 해당 프로토콜의 대리인을 ScanView으로 전달해야합니다. 이렇게 하나 을 만드십시오.이제

protocol IsbnDelegate { 
    func passData(isbnStr: String) 
} 

import UIKit 
import AVFoundation 
import Foundation 


class ScanView : UIViewController, AVCaptureMetadataOutputObjectsDelegate { 



let session   : AVCaptureSession = AVCaptureSession() 
var previewLayer : AVCaptureVideoPreviewLayer! 
var detectionString : String! 
let apiKey : String = "---------dddddd" 
var delegate: IsbnDelegate? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // For the sake of discussion this is the camera 
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

    // Create a nilable NSError to hand off to the next method. 
    // Make sure to use the "var" keyword and not "let" 
    var error : NSError? = nil 
    var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
    do { 
     input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
    } catch let myJSONError { 
     print(myJSONError) 
    } 

    // If our input is not nil then add it to the session, otherwise we're kind of done! 
    if input != AVCaptureDeviceInput() { 
     session.addInput(input) 
    } 
    else { 
     // This is fine for a demo, do something real with this in your app. :) 
     print(error) 
    } 

    let output = AVCaptureMetadataOutput() 
    output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
    session.addOutput(output) 
    output.metadataObjectTypes = output.availableMetadataObjectTypes 


    previewLayer = AVCaptureVideoPreviewLayer(session: session) 
    previewLayer.frame = self.view.bounds 
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
    self.view.layer.addSublayer(previewLayer) 

    // Start the scanner. You'll have to end it yourself later. 
    session.startRunning() 

} 



// This is called when we find a known barcode type with the camera. 
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

    var highlightViewRect = CGRectZero 
    var barCodeObject : AVMetadataObject! 
    let barCodeTypes = [AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code] 


    // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
    for metadata in metadataObjects { 

     for barcodeType in barCodeTypes { 

      if metadata.type == barcodeType { 
       barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

       highlightViewRect = barCodeObject.bounds 

       detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

       self.session.stopRunning() 

       self.alert(detectionString) 

       // Daum Book API 호출 
       let apiURI = NSURL(string: "https://apis.daum.net/search/book?apikey=\(apiKey)&q=\(detectionString)&searchType=isbn&output=json") 

       let apidata : NSData? = NSData(contentsOfURL: apiURI!) 

       NSLog("API Result = %@", NSString(data: apidata!, encoding: NSUTF8StringEncoding)!) 


       //Here We are passing the data of your ScanView to UploadMain 
       self.delegate.passData(self.detectionString!) 

       break 
      } 

     } 
    } 

    print(detectionString) 
    self.navigationController?.popViewControllerAnimated(true) 

} 



func alert(Code: String){ 
    let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

    // for alert add .Alert instead of .Action Sheet 
    // start copy 
    let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 
     { 
      (alertAction:UIAlertAction!) in 

      // action when pressed 
      self.session.startRunning() 
    }) 


    actionSheet.addAction(firstAlertAction) 

} 

} 
처럼 ScanView의 코드를 변경 UploadMain에서이 프로토콜을 상속하고 그 후

class UploadMain: UIViewController,UITextFieldDelegate,IsbnDelegate { 

    //your code 

    //Add this method 
    func passData(isbnStr: String) { 
      self.ISBN.text = isbnStr 
    } 

    //Also override prepareForSegue like this 

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
      let destVC = segue.destinationViewController as! ScanView 
      destVC.delegate = self 
    } 
} 

ScanViewdelegate 개체를 만들고 아래처럼 UploadMain에 그 방법 passData를 오버라이드 (override)

에 대한 자세한 내용이 링크

1) Apple Documentation
2) Tutorial 1
3)이 당신을 도울 것입니다 Tutorial 2

희망을 따릅니다.

+0

고맙습니다! 그것은 작동 ..! 나는 프로토콜에 대해 더 공부해야만한다. – kimpro

0

당신이 뷰 컨트롤러에서 다시 데이터를 를 전달하는 나타납니다.

당신은 당신이 그 뷰 컨트롤러의 새로운 인스턴스를 생성하고,이를 성공적으로 데이터를 수신 if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { UploadVC.ISBNstring = self.detectionString! }

를 호출 할 때 (그러나 당신이 그것을 사용하지 않을 수있다).

은 무엇 당신이하고자하는 것은 실제로 몇 가지 좋은 자습서 ScanView 당신이를 만드는에서

text
video

+0

매우 고맙습니다! 그것은 작동합니다! 블로그는 매우 도움이되었다! – kimpro

+0

텍스트 튜토리얼 또한 초 VC를 인스턴스화합니다 ... –

+0

'// 1. SecondViewController 인스턴스화 secondViewController = self.storyboard? .instantiateViewControllerWithIdentifier ("SecondViewController") as! SecondViewController' –

관련 문제