I wrote the source code at the bottom.
I gave File's Owner the IconHeader class and after connecting the imageView as an IBOutlet, when I run the application, my application crashes and I get the following error.
Thread 1: "[<NSObject 0x6000030c8860> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key iconImageView."
Then I removed ImageView from inpector and deleted IconHeader in File's Owner from class and added IconHeader to View's class. I chose Icon Header from Object tab while connecting ImageView.
This time, when I run the application, the following text appears on the console. "Then I removed ImageView from inpector and deleted IconHeader in File's Owner from class and added IconHeader to View's class. I chose Icon Header from Object tab while connecting ImageView."
MainViewController:
final class MainViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
var viewModel: MainViewModelProtocol? {
didSet {
viewModel?.delegate = self
}
}
override func viewDidLoad() {
super.viewDidLoad()
preapreTableView()
registerCellsForTableView()
registerHeaderForTableView()
viewModel?.fetchAgents()
}
private func preapreTableView() {
tableView.delegate = self
tableView.dataSource = self
}
private func registerCellsForTableView() {
let descriptionCellName = String(describing: DescriptionCell.self)
let descriptionCellNib = UINib(nibName: descriptionCellName, bundle: .main)
tableView.register(descriptionCellNib, forCellReuseIdentifier: descriptionCellName)
}
private func registerHeaderForTableView() {
let iconHeaderName = String(describing: IconHeader.self)
let iconHeaderNib = UINib(nibName: iconHeaderName, bundle: nil)
tableView.register(iconHeaderNib, forHeaderFooterViewReuseIdentifier: iconHeaderName)
}
}
MainViewController Extension:
extension MainViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let section = viewModel?.cellType[section]
else { return nil }
if case .description = section {
guard let iconHeader = tableView.dequeueReusableHeaderFooterView(withIdentifier: String(describing: IconHeader.self)) as? IconHeader
else { return nil }
return iconHeader
}
return nil
}
}
IconHeader:
final class IconHeader: UITableViewHeaderFooterView {
@IBOutlet weak var iconImageView: UIImageView!
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
fatalError("init(coder:) has not been implemented")
}
private func commonInit() {
if let view = loadViewFromNib() {
view.frame = bounds
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
contentView.backgroundColor = .red
contentView.addSubview(view)
}
}
private func loadViewFromNib() -> UIView? {
let nibName = String(describing: IconHeader.self)
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}



First, you're doing more work than needed...
Let's start with changing the
IconHeaderto this:Next we create a new, Empty User Interface File:
and save it as
IconHeader(with default .xib extension).Add a plain
UIView:and set Simulated Metrics -> Size to Freeform:
Resize it to make it easy to work with (the size for the moment doesn't matter), and assign its class to
IconHeader:Drag in a
UIImageView... constrain it centered, at 30x30 ... give it a systemYellow background so we can see its frame, and any image (I used the Swift SF Symbol with Red Tint color) ... and connect the@IBOutlet:Now let's use a simplified view controller so we can run it without your
viewModel. We'll use a defaultUITableViewCellclass, 10 sections, 2 rows in each section:Running that, we get:
Unfortunately, even though we are not setting any background colors, you will see this error / warning message for each section header in the debug console:
To get rid of that, in your xib, change the view's background color from
System BackgroundtoDefault:No more error messages.
To actually set the background color, we can do that either in
viewForHeaderInSection:Output:
or, we can set a default color in the
IconHeadercell class init: