Thiago Loddi
Thiago Loddi

Reputation: 2340

UITableView throws exception when adding UIView to tableFooterView

I'm trying to implement a UITableView. I've already been able to make it work, but it kept showing the lines in the empty cells, so I looked online and found a solution that was to put a UIView in the tableFooterView, so I did it:

self.tableView.tableFooterView = IUView()

In the first table view I set up it worked fine, but know Im trying to implement a second one and its not working. If i run it without the line above, everything works fine, but the I get lines in the empty cells. If I run with the line above, I get a 'fatal error: unexpectedly found nil while unwrapping an Optional value', and XCode points the error in this line:

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int)     -> Int {
        return self.itemsList.count // Throws error: Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
}

Does anyone knows why this is happening? Or how can I fix it? Or if there is a better, righter way to hide to lines on empty cells? Thanks!

Here my UIViewController class for reference:

class InfoPickerViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var infoPicker: UITableView!

private var pageTitle: String!
private var itemsList: [String]!

convenience init(title: String){
    self.init()

    self.pageTitle = title
}

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController?.navigationBar.tintColor = UIColor.whiteColor()
    self.title = self.pageTitle

    self.infoPicker.delegate = self
    self.infoPicker.dataSource = self
    self.infoPicker.tableFooterView = UIView()
    self.infoPicker.registerNib(UINib(nibName:"SimpleTableViewCell", bundle: nil), forCellReuseIdentifier: "simpleCell")

    populateItemsList()
}

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

func populateItemsList() {
    let clientsInfo = ClientsInfo()
    self.itemsList = []

    switch self.pageTitle {
        case "Cliente": self.itemsList = clientsInfo.getClientsList()
        default: self.itemsList = []
    }
}

// MARK: TableView

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let listItemCell = infoPicker.dequeueReusableCellWithIdentifier("simpleCell", forIndexPath: indexPath) as! SimpleTableViewCel

    listItemCell.itemLabel.text = self.itemsList[indexPath.row]

    return listItemCell
}

}

Upvotes: 0

Views: 514

Answers (1)

Dan Beaulieu
Dan Beaulieu

Reputation: 19964

I don't have my mac with me but I'll give this a shot. At the top of your ViewController, update the following line:

private var itemsList: [String] = [] {
    didSet {
        dispatch_async(dispatch_get_main_queue(), { 
            self.tableView.reloadData()
        })
    }
}

We're initializing your itemsList array which will have an Element count of 0, this way your numberOfRowsInSection won't crash because your itemsList is nil. Then, when your populateItemsListfunction gives itemsList a real value, your table view will reload with data on the main thread.


from comments:

I described where the error came from in my answer. You've got an uninitialized itemsList: [String]!, when your numberOfRowsInSection tries to access the value, the value is nil and your application crashes. My solution resolves this by giving your array an initial value.

Upvotes: 1

Related Questions