Search code examples
swiftuicontainerviewchildviewcontrollerparentviewcontroller

iOS - How to set imageview of a parent view controller through child container?


I am currently using a container view and I want to change the value of parent view controller imageView through child view controller using delegates, but it always returns nil.

import UIKit

protocol updateImage {
    func userIsDone(image:UIImage)
}

class ViewController: UIViewController, updateImage{

    @IBOutlet weak var imageView:UIImageView!
    var image = UIImage(named: "hello.png")

    override func viewDidLoad() {
        super.viewDidLoad()
        self.imageView.image=self.image
    }

    func userIsDone(image: UIImage) {
        self.image=image
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "containerChild"{

            let nextView = segue.destinationViewController as! ControllerChild
            nextView.image=self.image
            nextView.delegate=self
        }
    }
}

class ControllerChild:UIViewController{

    var image=UIImage(named: "newhello.png")
    var delegate: updateImage? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func changeImage(sender:UIButton){

        if(delegate != nil){
            self.delegate!.userIsDone(self.image!)
            print("I am Called!")
        }
    }
}

Solution

  • Remove this line:

    nextView.image = image
    

    And change the userIsDone function to:

    func userIsDone(image: UIImage) {
        imageView.image = image
    }
    

    hello

    As side notes:

    • In Swift you don't need to use self outside of blocks/closures. For example, you don't need to self.imageView.image = self.image -- just imageView.image = image will do.
    • Protocols should be upper-cased, like UpdateImage (instead of updateImage).
    • You don't need that extra .png to reference images, just the title, E.g.: "hello".

    Apple describes Swift code conventions in their awesome Swift book.

    Here is the code, refactored (Swift 3):

    import UIKit
    
    protocol UpdateImageProtocol {
        func userIsDone(image: UIImage)
    }
    
    class ViewController: UIViewController, UpdateImageProtocol {
    
        @IBOutlet weak var imageView: UIImageView!
        var image = UIImage(named: "hello")
    
        override func viewDidLoad() {
            super.viewDidLoad()
            userIsDone(image: image!)
        }
    
        func userIsDone(image: UIImage) {
            imageView.image = image
        }
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "containerChild" {
                let nextView = segue.destination as! ChildViewController
                nextView.delegate = self
            }
        }
    }
    
    class ChildViewController: UIViewController {
    
        var image = UIImage(named: "newHello")
        var delegate: UpdateImageProtocol?
    
        @IBAction func changeImage(sender: UIButton) {
            delegate?.userIsDone(image: image!)
        }
    }