0

I'm trying to follow along the following Using Auto Layout in UITableView for dynamic cell layouts & variable row heights top answer in Swift but for the IOS 7 version to mitigate some bugs in the IOS 8.

Right now, my custom cell class is:

class PostCell: UITableViewCell {

    @IBOutlet var name: UILabel!
    @IBOutlet var timestamp: UILabel!
    @IBOutlet var postBody: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

In my Storyboard I set my custom class as the class for the cell. I don't know if I have to use my reuseIdentifier anywhere. I don't know how to get that working in the next piece of code.

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    var cell = PostCell()

    var post = self.posts[indexPath.row]

    cell.name.text = post.name
    cell.timestamp.text = post.timestamp
    cell.postBody.text = post.body

    cell.setNeedsUpdateConstraints()
    cell.updateConstraintsIfNeeded()

    cell.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(feed.bounds), CGRectGetHeight(cell.bounds))

    cell.setNeedsLayout()
    cell.layoutIfNeeded()

    var height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height

    height += 1.0

    return height
}

I thought that would work, but when I call cell.name.text = post.name, I get an EXC_BAD_INSTRUCTION. I'm guessing the cell isn't properly hooked up to the storyboard somehow or something. How do I fix this?

Community
  • 1
  • 1
David
  • 7,028
  • 10
  • 48
  • 95

1 Answers1

1

The problem is that you don't understand how nibs work. You have set up your PostCell to be configured when it is loaded from its nib:

class PostCell: UITableViewCell {
    @IBOutlet var name: UILabel!
}

So that means that name is nil - until this cell is instantiated from the nib, at which time the outlet will be hooked up. But then later you say:

var cell = PostCell()

But that is the wrong PostCell! You didn't load it from the nib; you just made one out of whole cloth. So since there was no nib-loading, the outlet (as you rightly suspect) was naturally never connected, and so cell.name is nil.

So the solution is: do not make one out of whole cloth. Load it from the nib.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Honestly, I don't even know what a nib is. How would I load it from the nib? – David Feb 01 '15 at 00:48
  • Tell me the name of the nib. - Or is it configured in the storyboard? – matt Feb 01 '15 at 00:50
  • I set the identifier for the cell to be "gatePost". Yes it is made in the Storyboard – David Feb 01 '15 at 00:53
  • Okay, so try this: instead of saying `PostCell()`, ask the `tableView` to dequeue you a cell with the `"gatePost"` identifier. It will get it from the nib (the one in the storyboard) and so its outlets should be hooked up when it comes to you! – matt Feb 01 '15 at 00:54
  • I avoided that because I read somewhere that unless you're in the cellForRowAtIndexPath method, you should avoid dequeueing. – David Feb 01 '15 at 00:56
  • You have no choice. You are the one who set it up this way. Now this is your only way to get cells whose outlets are configured. – matt Feb 01 '15 at 00:57
  • 1
    It isn't the way I would have done it; I would have used a `.xib` file. But now you're kind of stuck. Anyhow, just try it for now. You can change architectures later if you want; right now let's just try to get you a cell. – matt Feb 01 '15 at 00:57