Search code examples
iosswiftiboutletuicontainerview

Custom container: @IBOutlets nil even though view is displaying correctly


I have created a UIViewController. Within this view controller I have a container view.

In the code I instantiate the container view like so:

var answerButtons: AnswerButtonsViewController!

override func viewDidLoad() {
    super.viewDidLoad()

    answerButtons = AnswerButtonsViewController()
    answerButtons.delegate = self

    println(answerButtons.name) // This prints out the correct string
    println(answerButtons.answerOne) // This prints out nil
    println(answerButtons.buttons) // This prints out an empty array

    retrieveSelectedCategory(selectedCategory!)
}

However the container view is definitely instantiate because within the container view class I set the background color of the UIButton's and this displays correctly within my app.

Here is the code from my container view:

@IBOutlet var answerOne: UIButton!
@IBOutlet var answerTwo: UIButton!
@IBOutlet var answerThree: UIButton!
@IBOutlet var answerFour: UIButton!
@IBOutlet var answerFive: UIButton!
@IBOutlet var answerSix: UIButton!
@IBOutlet var answerSeven: UIButton!
@IBOutlet var answerEight: UIButton!

var buttons: Array<UIButton> = []

var name = "Is this set"

var delegate: AnswerButtonsViewControllerDelegate?

override func viewWillAppear(animated: Bool) {
    addAnswerButtonsToArray()
    buttons.map(customiseButtons)
}

func addAnswerButtonsToArray() {
    buttons.append(answerOne)
    buttons.append(answerTwo)
    buttons.append(answerThree)
    buttons.append(answerFour)
    buttons.append(answerFive)
    buttons.append(answerSix)
    buttons.append(answerSeven)
    buttons.append(answerEight)
}

func customiseButtons(button: UIButton) {
    button.layer.cornerRadius = 5
    button.setTitleColor(UIColor.blackColor(), forState: .Normal)
    button.backgroundColor = GSNColor.veryLightGrayColor()

    var title: String! = button.titleLabel?.text
    title.replaceRange(title.startIndex...title.startIndex, with: String(title[title.startIndex]).capitalizedString)
    button.titleLabel?.text = title
}

@IBAction func answerButtonPressed(sender: UIButton) {
    delegate?.answerButtonPressed(sender)
} 

Also the IBAction of the buttons work.

So I can't understand why my property answerButtons is initiated and the name property is set ok. However the properties are nil when printed and the array empty. Yet the view is being displayed correctly.

Any insights would be much appreciated and if you need any more details please let me know.

Edit

Here is a picture of storyboard with the connections:

enter image description here


Solution

  • The controller embedded in the container view is instantiated at the same time that the controller with the container view is. You should not instantiate it yourself. You only need to get a reference to it. A controller in a container view is a child view controller of the controller whose subview is the container view. Instead of this,

    answerButtons = AnswerButtonsViewController() // this creates another instance that you never use, and is never on screen
    

    You should have this,

    answerButtons = self.childViewControllers[0] as AnswerButtonsViewController