简体   繁体   中英

Adding a view loaded from a NIB to a Custom Table View Cell doesn't work as expected

I have been playing around with reusing views inside a table view cell. I have a custom table view cell and another reusable view that I use in the cell and in other parts of my app. The reusable view is defined in a XIB file and linked accordingly with it's class definition.

I am having strange behaviour when I try to get the view inside a custom table view cell

DevicesTableViewCell <- Custom UITableViewCell to hold a view that is in another NIB.

DeviceView <- Custom reusable view that can be used in a cell and in other parts of the app, like a Stack View.

Now, when I try to load the nib and add it to the Cells Content View, the view doesn't appear. However if I try to add it to a container view inside the table view cell, it does work.

Cell setup code :

    let devicesName         = sectionDataArray[MasterSection.devices.rawValue].reuseId
    let devicesNib          = UINib(nibName: devicesName, bundle: nil)
    tableView.register(devicesNib, forCellReuseIdentifier: devicesName)
  1. Code where view does not appear :

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: sectionDataArray[indexPath.section].reuseId) print ("-- Showing devices cell") let deviceCell = cell as! DevicesTableViewCell // Optimise this, we way not necessarily need to load this view every single time if deviceCell.deviceView == nil { deviceCell.deviceView = Bundle.main.loadNibNamed("DeviceView", owner: self, options: nil)?.first as! DeviceView deviceCell.containerView.isHidden = true deviceCell.contentView.addSubview(deviceCell.deviceView) let views = ["deviceView" : deviceCell.deviceView] deviceCell.deviceView.translatesAutoresizingMaskIntoConstraints = false deviceCell.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[deviceView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) deviceCell.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[deviceView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) } // TODO - Setup cell data contents return deviceCell } 
  2. Code where view does appear :

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: sectionDataArray[indexPath.section].reuseId) print ("-- Showing devices cell") let deviceCell = cell as! DevicesTableViewCell // Optimise this, we way not necessarily need to load this view every single time if deviceCell.deviceView == nil { deviceCell.deviceView = Bundle.main.loadNibNamed("DeviceView", owner: self, options: nil)?.first as! DeviceView //deviceCell.containerView.isHidden = true deviceCell.containerView.addSubview(deviceCell.deviceView) let views = ["deviceView" : deviceCell.deviceView] deviceCell.deviceView.translatesAutoresizingMaskIntoConstraints = false deviceCell.containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[deviceView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) deviceCell.containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[deviceView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) } // TODO - Setup cell data contents return deviceCell } 

Custom Cell Code :

class DevicesTableViewCell: UITableViewCell {

@IBOutlet weak var containerView: UIView!
var deviceView: DeviceView!

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
}

}

RESULT:

  1. Adding to contentView -> Nothing appears but a white background.

  2. Adding to containerView -> The view appears as normal and is contained in the cell with the correct auto layout constraints internally.

NOTES: The containerView is in the Custom Table Cell View XIB file. Container view has autolayout constraints bounding its view to the table view cell view with margins of 0.

QUESTION: Can anyone explain why in this particular case the Content view does not correctly display its subviews ?

The problem was that I had the wrong object inside the XIB file.

Inside the DevicesTableViewCell.xib, the view created was a UIView object. Not a UITableViewCell object.

If you instantiate a cell from a XIB, make sure that view object is created from a UITableViewCell.

This is because the UITableViewCell object has a content view wrapped inside it.

After changing the XIB file adding objects to the content view worked correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM