2

I am developing an app with swift in Xcode 6 GM using storyboard. On my viewcontroller if I drag and drop any view and connect it with an IBOutlet in the related viewcontroller file, that outlet is always nil in viewDidLoad and I always get BAD_INSTRUCTION error if I try to interact with that outlet like changing the title of a button or anything else because that referenced outlet is always nil and I cannot understand why.. I've checked that the viewcontroller on the storyboard is owned by my viewcontroller file in identity inspector under custom class option.. Is it an issue of Xcode and someone else is getting the same problem or I'm doing something wrong?

EDIT 1:

this is the first viewcontroller that is launched

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let vc = segue.destinationViewController as TableViewController
    vc.prepare(/*initializing things..*/)

}

//and this is the viewcontroller with my tableview outlet and custom cell

import UIKit

class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var tableView: UITableView!


//this array contains the date to display in cells and in viewDidLoad is correctly  initialized with all the right data..
private var toVisualize:[Visualizable] = []

 override func viewDidLoad() {
    super.viewDidLoad()
    /*I need to initialize the tableview even if it's an outlet rightly connected to the storyboard because it's always nil when viewDidLoad is called*/
    self.loadArticles()
    self.tableView = UITableView(frame: self.tableView.frame, style: UITableViewStyle.Plain)
    //navigationController?.hidesBarsOnSwipe = true
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.allowsSelection = true
    var cell = UINib(nibName: "MyCell", bundle: nil)
    /*first I've used a prototype cell defined in the storyboard and a class with the related outlets and all connected in the right way but the result was a blank screen so I've tried to use a xib file to define the layout of my custom cell and the tableview started showing my cells.. but still I can't figure out why the tableview is nil*/
    self.tableView.registerNib(cell, forCellReuseIdentifier: "Cell")
    //self.tableView.registerClass(CellaTableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
    self.view.addSubview(self.tableView)
    self.tableView.reloadData()
    // Do any additional setup after loading the view.
}


func prepare(/*preparing function used from first view controller..*/)->()
{
    //this func is not changing anything because I've added it later..
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//this function is correctly working and showing the cells when the tableview is initialized
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = self.tableView?.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyCell

    var toLoad = self.toVisualize[indexPath.row].getVisualizableProperties()



    cell.loadItem(toLoad.title, descr: toLoad.descr, date: toLoad.date)


    if let URL = toLoad.thumbUrl
    {
        var image = self.imageCache[URL]

        if( image == nil ) {
            // If the image does not exist, we need to download it
            var imgURL: NSURL = NSURL(string: URL)

            // Download an NSData representation of the image at the URL
            let request: NSURLRequest = NSURLRequest(URL: imgURL)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
                if error == nil {
                    image = UIImage(data: data)

                    // Store the image in to our cache
                    self.imageCache[URL] = image
                    dispatch_async(dispatch_get_main_queue(), {
                        if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as? MyCell {
                            cellToUpdate.thumbnail?.image = image
                        }
                    })
                }
                else {
                    println("Error: \(error.localizedDescription)")
                }
            })

        }
        else {
            dispatch_async(dispatch_get_main_queue(), {
                if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as? MyCell {
                    cellToUpdate.thumbnail?.image = image
                }
            })
        }

    }

    return cell
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView!,heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat
{
    return 120.0
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.toVisualize.count
}

}

First I was using presentViewController to push the TablewViewController programmatically and my outlet tableview was always nil in viewDidLoad, then I've tried to use the "Triggered Segues" action of buttons in my ViewController to push the TableViewController (ViewController in it's view contains only 4 buttons with presenting segues actions that all present TableViewController.. nothing special or strange) and the tableview started to be initialized and then I've commented out the init method of tableview and delegate setting (delegate and dataSource are already set in storyboard) but the result is again a blank screen showing nothing.. I've double checked all the connections with storyboard and various identifiers so they are all correctly set.. Can't figure out what's the problem

  • Can you post your code? – Steve Rosenberg Sep 22 '14 at 23:00
  • I've changed my code.. First I was pushing viewcontroller programmatically by using 'code'presentViewController(vc, animated: true, completion: nil)'code' and now I've added an action on a button click that pushes the segue and now my outlet that is a tableview is initialized and not nil but now the problem is that my custom cells of the tableview are working only if I use a xib file to define the cell layout and not with a prototype cell defined directly on the tableview in storyboard with it's related model class and respective outlets.. – user3676870 Sep 23 '14 at 07:21
  • I think the problem comes out if I use to push viewcontrollers programmatically, if I use the "Triggered Segues" options the outlets are correctly initialized and I can interact with them, but still the tableview not shows my custom cells event if it's initialized (never calls cellForRowAtIndexPath) – user3676870 Sep 23 '14 at 09:24

2 Answers2

1

I had the same problem in Xcode 6.1 beta and finally the outlets stopped being nil after removing the custom cell registration line from my viewDidLoad method:

// Remove this: self.tableView.registerClass( MyTableViewCell.self, forCellReuseIdentifier: "MyIdentifier" )

Works when instantiating from a storyboard and pushing or adding as a subview to another view programmatically.

Patrick Lynch
  • 2,742
  • 1
  • 16
  • 18
0

that outlet is always nil in viewDidLoad and I always get BAD_INSTRUCTION error if I try to interact with that outlet like changing the title of a button or anything else because that referenced outlet is always nil and I cannot understand why

Try referencing the control in the viewWillAppear or viewDidAppear functions instead.

When viewDidLoad runs, your app won't have created the views and controls yet, so it's too early to modify their contents.

Also, in your Storyboard, right-click on your control, and check that you have something listed under the "Referencing Outlets" section, with the circle filled in on that row. (That just confirms that you do have a variable bound to that control.)

enter image description here

Mike Gledhill
  • 27,846
  • 7
  • 149
  • 159