29

What I want to achieve:

User presses the button in the ViewController then, the color of the button placed in the container view should change its color to red.

How can I get access of the button placed in the container view, from the ViewController?

enter image description here

Tom el Safadi
  • 6,164
  • 5
  • 49
  • 102

4 Answers4

62

Step by step:

  1. Name the segue between your view controller and container view controller.
  2. Add a property to your view controller which will contain the container view controller.
  3. In your view controller implement a method prepareForSegue(_:sender:).
  4. In the method check if segue.identifier equals the identifier you specified in step 1.
  5. If true, then save the segue.destinationViewController to your property from step 2.
  6. Now you have the container view controller stored in your property so you can do customization from your class. You should have the view controller stored in viewDidLoad() method already.

Example:

var containerViewController: YourContainerViewControllerClass?
let containerSegueName = "testSegue"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == containerSegueName {
        containerViewController = segue.destinationViewController as? YourContainerViewControllerClass
    }
}
sunshinejr
  • 4,834
  • 2
  • 22
  • 32
  • Thanks very much for your detailed answer but where can I lets say edit the MyButton.backgroundColor = UiColor.blackColor() ? and how will I add an override function in the action of the button placed in my viewcontroller? – Tom el Safadi Nov 22 '15 at 19:12
  • `containerViewController.MyButton.backgroundColor..` in your view controller (not the container view controller) – sunshinejr Nov 22 '15 at 19:37
  • Yep that worked for me thanks a lot for the detailed answer!! – Tom el Safadi Nov 27 '15 at 14:39
  • 1
    Awesome! Thank you so much! – Stefan DeClerck Aug 12 '16 at 04:29
  • 3
    Need to use `override func prepare(for segue: UIStoryboardSegue, sender: Any?) {` for swift 3 & Xcode 8.3 otherwise this method won't be called – oOEric Sep 12 '17 at 13:16
28

I recommend not to rely on segue.identifier, but rather test for destination type directly:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let vc = segue.destination as? YourViewController {
        vc.someVariable = true
    }
}

This way you avoid mistakes with a misspelled segue name.

lewis
  • 2,936
  • 2
  • 37
  • 72
Andrey Gordeev
  • 30,606
  • 13
  • 135
  • 162
  • 3
    This should be the accepted answer. If you have more then one UIContainerView and try the .identifier approach you will fail :D thanks @andrey – Tom Aug 25 '17 at 16:29
  • @Tom I think you did not understand the question, accepted Answer is correct, but that answer can be better with this destination approach of Andrey. I used the both answers to solve my problem :D Thanks. :) – Muhammad Danish Qureshi Apr 20 '22 at 08:07
  • Ahh this is super old. I avoid using storyboard and xibs now. – Tom Apr 21 '22 at 09:52
  • @Tom me too. UI by code is great. – Andrey Gordeev Apr 22 '22 at 05:01
2

Swift 4, Xcode 9.4.1

var contentViewController : UIContentViewController?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == containerSegueName {
       contentViewController = segue.destination as? UIContentViewController
    }
}
Saranjith
  • 11,242
  • 5
  • 69
  • 122
1

Swift 3 for macOS:

// MARK: - Container View Controller

var containerViewController: ContainerViewController?

let containerSegueIdentifier = "Container Segue"

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
    if segue.identifier == containerSegueIdentifier {
        if let connectContainerViewController = segue.destinationController as? FormationViewController {
            formationViewController = connectContainerViewController
        }
    }
}

Check identifier and controller class.

asdf
  • 952
  • 14
  • 13