简体   繁体   中英

How can I connect a view controller to its delegate in a storyboard?

I'm trying to figure out how to get a reference to another view controller (delegate) in a project that uses a storyboard. The delegate has been nil in all of my attempts so far.

I have a project right now that's pretty simple and has just three view controllers.

  • MainScreenViewController: The root view controller, and contains the buttons that segue into the other view controllers (presented modally).

  • PhotoScanViewController: Has the user pick/take a photo, which it then scans to produce some data. The user can can then save the photo and the associated data.

  • PhotoListTableViewController: Contains the list of photos with their data that the user has saved.

From this, I need PhotoScan to send the data over to PhotoList when a user saves a photo. I figured that I should do this using the delegate pattern, with PhotoList being a delegate that receives messages from PhotoScan. I just can't seem to figure out how to get a reference to PhotoList from PhotoScan when I'm using a storyboard. 故事板层次 What I've tried:

1) From looking at similar questions, I saw that most of the time people set delegates when prepareForSegue:sender: is called. However, this does not work in my case, since PhotoScan and PhotoList are not connected by a segue in the view hierarchy.

2) I've tried making the delegate an IBOutlet to wire up in the storyboard, but it seems that I cannot connect outlets from one scene into another.

3) Since I couldn't connect it inside the storyboard, I tried to programmatically connect it inside the AppDelegate.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    // Get the storyboard instance
    let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())

    // Get references to controllers
    let photoScanViewController = storyboard.instantiateViewControllerWithIdentifier("PhotoScanViewController") as PhotoScanViewController
    let photoListTableViewController = storyboard.instantiateViewControllerWithIdentifier("PhotoListTableViewController") as PhotoListTableViewController

    // Set delegate
    photoScanViewController.photoDelegate = photoListTableViewController

    return true
}

This didn't work either: photoListDelegate was still nil when I ran the app. I think what's happening is that instantiateViewControllerWithIdentifier: is giving me new instances for the view controllers rather than the ones actually being used when the app runs.

At this point, I don't know what else to do other than changing up my view hierarchy so that I can use prepareForSegue:sender: and set the delegate there like everyone else.

Your decision of delegation is correct pattern -- only to the wrong view controller.

When the user saves a photo from PhotoScanViewController, have all the data data delegate it back to the MainScreenViewController. Now that you have the data, when the user taps on the "list" button, supply the newly fetched data to the PhotoListViewController. This should work out for you.

Here is some code to help you out:

class ImageScannerViewController {
    var delegate:ImageScannerViewControllerDelegate?
    var imageData:NSData? //
    func getScannedImageData() -> NSData {

    //Method to get imageData here

    }
    @IBAction didTapSaveButton(sender:AnyObject?) {
      imageData = self.getScannedImageData()
      self.delegate?.imageScannerViewController(self,imageData:imageData!))

    }
}

protocol ImageScannerViewControllerDelegate {
    func imageScannerViewController(imageScanerViewController, didSaveImageWithImageData, imageData:NSData)
}

In your MainScreenViewController

class MainScreenViewController:UIViewController,ImageScannerViewControllerDelegate {
    var imageData:NSData?
    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
       if (segue.identifier == "scannerViewControllerSegue") {
        // pass data to next view
           let scannerViewController = segue.destinationViewController as ImageScannerViewController
           scannerViewController.delegate = self
       }
   }
    func imageScannerViewController(imageScanerViewController, didSaveImageWithImageData, imageData:NSData) {
      self.imageData? = imageData
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM