Search code examples
iosiphoneuipageviewcontroller

Call a function in a detail PageViewController from the ViewController that loads it


I have a PageViewController that loads different photo albums, each foto album is loaded from a different view controller (album1ViewController... album3ViewController), as shown below. Storyboard

Each view controller (album1... album3) is loaded from a navigation view controller so they load a nav bar. I wanted to add a save to camera roll button to the navigation bar so I put this code in the ItemVC (the one that loads the image) and also in the PageViewController, but it didn't activate the save button:

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(saveToCameraRoll))

So I figured that the only way to add the button programatically was inside the albumsVCs. (I try adding the bar in the storyboard in ItemsVC but it didn't show properly). But now I want to call the function SaveToCameraRoll in a button called by album#ViewController with the image in ItemsViewController. I've tryied first leaving the function inside ItemsVC and trying to call it from albumVC like this:

let vc = self.storyboard?.instantiateViewController(withIdentifier: "ItemController") as! ItemViewController
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Guardar en Fotos", style: .plain, target: self, action: #selector(vc.saveToCameraRoll))

But the app crashes. with this error:

unrecognized selector sent to instance 0x7fca05d32e60

Then I tried in albumVC adding the SaveToCameraRoll function like this:

@objc func saveToCameraRoll() {
    let vc = self.storyboard?.instantiateViewController(withIdentifier: "ItemController") as! ItemViewController
    let imageData = UIImagePNGRepresentation(vc.contentImageView.image!)
    let compresedImage = UIImage(data: imageData!)
    UIImageWriteToSavedPhotosAlbum(compresedImage!, nil, nil, nil)
    
}

In the second case I algo get an error and a crash, in the line:

let imageData = UIImagePNGRepresentation(vc.contentImageView.image!)

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Is there a way to add this function? or is there a simpler way to archive this? Thanks!


Solution

  • I would suggest setting up your album view controllers to have a delegate property.

    Define a protocol ParentProtocol that implements your saveToAlbum method.

    Make you ItemController conform to that protocol.

    In your page view controller, as you load pages, set their delegate property to self.

    In your Album view controllers, create an IBAction method in the Album view controller that sends a saveToAlbum method to the delegate.

    That's a pretty common pattern for forwarding messages from child view controllers up to the parent.

    I created a project on Github recently called TabBarControllers that does something very similar with tab bar controllers (A tab bar controller manages 2 or more child view controllers as tabs.) in that case the child view controllers are loaded from the storyboard at startup through a segue. In your case you'll have to write code that sets the delegate as it loads the album view controllers, but the idea is very similar.