SuperDuperTango SuperDuperTango - 9 months ago 46
iOS Question

Can't set UINavigationControllerDelegate programatically (but can set via storyboard)

(XCode 8.1, Swift 3. Example in github at under the tags "byhand" and "storyboard")

I can set a UINavigationControllerDelegate by setting it up in a storyboard exactly as explained in the page Here's an image:

Here's a pic of how it looks for me:

enter image description here

This works great.

However, if I don't setup the delegate in the storyboard, but instead try to assign the same delegate programatically, the delegate methods aren't called.

let delegate = JamNavigationControllerDelegate()
NSLog(String(describing: delegate))
navViewController.delegate = delegate
navViewController.pushViewController(view3ViewController, animated: false)
// and all subsequent push/pops don't use the delegate.

I put a test repo in github at There are two tags "byhand" and "storyboard" which should be self explanitory.

Any ideas?

Answer Source

navViewController.delegate is a weak var. This means that some other object must keep a strong reference to the delegate so that it stays alive. In your code snippet, delegate is only kept around until the end of that snippet (which I'm guessing is in a method). As soon as the snippet is over, the delegate var goes out of scope. The navViewController is the only other object with a reference to that variable, but it is a weak reference, which means it doesn't increase the retain count. So the retain count will be 0, the object will be deallocated, and navViewController.delegate will be nil. You will need to add a property to your view controller to keep a strong reference to the JamNavigationControllerDelegate, or make the view controller itself the delegate.