UITableViewCell is wider than its UITableView - ex

2019-08-23 01:48发布

问题:

Background

I have a UITableView with a single cell. Inside the cell is a UILabel. The cell, called PickerTableViewCell, gets its UI from a xib and adds it to its subview. This is done because this xib is used by many different custom cells.

Problem

It appears that when this cell is dequeued by the table view, its width extends beyond the table views width on the right hand side.

Here is the xib with the UILabel centred within the cell, followed by how it appears on the device. Notice how the label is off-centre on the device:

When I move the label to the very right of the cell (label.trailing = pickerCell.trailing + 0), it disappears off the right hand side. Below is how that looks in the xib followed by how it appears on the device:

When I align the UILabel to the left of the cell (label.leading = pickerCell.leading + 0), it correctly aligns to the left on the device.

Here is how the PickerTableViewCell loads the xib:

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)


        // load the xib to associate with
        let nib = Bundle.main.loadNibNamed("PickerTableViewCell", owner: nil, options: nil)
        if let view = nib?.first as? UIView{
            self.addSubview(view)
        }
    // ...
}

Here is how the tableview registers the cell:

self.tableView.register(PickerTableViewCell.self, forCellReuseIdentifier: "pickerCell")

And finally here is how it is dequeued:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "pickerCell") as! PickerTableViewCell
        return cell
}

Could anyone help understand what is going on?? Why is my cell seeming to extend beyond the width of the table view?

回答1:

While assigning any xib, you have to specify the frame. Here is the modified code:

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    // load the xib to associate with
    let nib = Bundle.main.loadNibNamed("PickerTableViewCell", owner: nil, options: nil)
    if let view = nib?.first as? UIView{
        self.addSubview(view)
        view.frame = bounds //Provide the frame
    }
    // ...
}


回答2:

In case of using Nib for cell design, don't register the cell class itself, register the nib instead.

Remove the code

init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 

And the registration process would be like

let cellNib = UINib.init(nibName: "YourNibName", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "Identifier")

Dequeue process is okay.