Reputation: 816
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)
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
}
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:
Adding to contentView -> Nothing appears but a white background.
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 ?
Upvotes: 1
Views: 1795
Reputation: 816
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.
Upvotes: 2