Rossco Rossco - 3 months ago 24
iOS Question

Label is found as nil despite being linked in IB

Swift3/Xcode 8.1

The following code...

class PageContentVC: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate{

var array = [String]()
var currentIndex = 0

override func viewDidLoad() {

array = ["1","2","3","4"]

self.dataSource = self
self.delegate = self
self.setViewControllers([helperFunction(index: currentIndex)], direction: .forward, animated: true, completion: nil)


func helperFunction(index: Int) -> UIViewController{

let newVC = storyboard?.instantiateViewController(withIdentifier: "PageContent") as! PageContent

print("currentIndex is: \(currentIndex)")
print("value at currentIndex is: \(array[currentIndex])")

newVC.PageContentLabel.text = array[currentIndex]

return newVC

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?{

if (currentIndex == 0) || (currentIndex == NSNotFound) {
return nil
currentIndex -= 1
return helperFunction(index: currentIndex)

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?{

if (currentIndex == array.count - 1) || (currentIndex == NSNotFound) {
return nil
currentIndex += 1
return helperFunction(index: currentIndex)

...crashes the app with an "Unexpectedly found nil whilst unwrapping an optional value" error at the following line:

newVC.PageContentLabel.text = array[currentIndex]

'PageContentLabel' is definitely linked via interface builder and when I comment out the offending line, the app runs fine.

What am I missing here?

Rob Rob

The label is nil because you've instantiated the view controller, but the view hierarchy defined in the storyboard, as configured in IB, hasn't finished being built yet. You should add a string property in your view controller and have helperFunction populate that, not the IBOutlet. Then, the viewDidLoad of PageContent should take that string property and use that to set the text of the UILabel. Bottom line, don't try to use the outlets until viewDidLoad has been called.