Problems using classes for reusable headers

I am following a tutorial to create reusable headers in my app, but I get the following error: "Thread 1: EXCBADACCESS (code=2, address=0x7ffeeb1eaff8)". I have tried everything but can't seem to get it working in my app. The example project works fine on its own but my app underlines "instantiate" as the problem

The swift file for the header:
Code Block
import UIKit
class HeaderView: UIView {
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var headerText: UILabel!
    let nibName = "HeaderView"
  
    required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            commonInit()
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
        
        func commonInit() {
            guard let view = loadViewFromNib() else { return }
            view.frame = self.bounds
            self.addSubview(view)
        }
      
        func loadViewFromNib() -> UIView? {
            let nib = UINib(nibName: nibName, bundle: nil)
            return nib.instantiate(withOwner: self, options: nil).first as? UIView
        }
    }


View controller:
Code Block
import UIKit
class StableViewController: UIViewController {
    @IBOutlet weak var header: HeaderView!
    @IBOutlet weak var viewButtons: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
     
    }


I tried your code and found that, with a slight mistake in a xib settings, it crashed with EXC_BAD_ACCESS.
Which is caused by stack overflow with infinite recursive call.

Aren't you setting the Custom Class of the main View of HeaderView.xib to HeaderView? If so, remove it and reset it to UIView.


I am following a tutorial

If it is a web resource and you can share the link to it, we can find something surer.
I wasn't able to send the link to the tutorial, but I changed the class of the .xib and now I get a new error:
Thread 1: "[<UIView 0x7fdab4512fa0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key headerText."
After changing the class, did you do an option-clean Build folder ?

I get a new error: 

Thanks for testing.
But your code causes stack overflow if the Custom Class of the main View is set to HeaderView.

We need to guess what the hack the tutorial is trying as you are not able to show the link.


So, I found a good article explaining some hack similar to what you are trying.

medium.com/better-programming/swift-3-creating-a-custom-view-from-a-xib-ecdfe5b3a960

This article says you need to set the Custom Class of the File's Owner to HeaderView. (Not the Custom Class of the main View.)
You should better try.
I did a clean build folder, but still getting this error: Thread 1: "[<UIView 0x7fb6b0d119b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key headerText."

I tried commenting out the bit where I change the headerText and the outlet for the header without result. Also checked for broken connections in the view controller. It's underlining AppDelegate in the error text with the same error. There is still a headerText outlet in HeaderView.swift. This isn't connected to anything since I changed the class of the HeaderView.xib, I can't see the file in assistant anymore so I deleted the connection. Still getting the same error

I deleted the connection.

Once you change the class after some connections were made, the xib may be broken. Try removing the xib and create a new one. And then set the right Custom Class to the File's Owner, and after that connect the outlets.
I tried a few more things and now the header is showing, but I am unable to attach the outlets in the HeaderView.Swift to the elements in the HeaderView.xib. As long as the .xib is set to UIView, I can't attach anything to the code. I only get UIView in the assistant

 I am unable to attach the outlets in the HeaderView.Swift to the elements in the HeaderView.xib. 

As far as I follow the instructions shown in the link I have shown, I can connect the IBOutlets using exactly the same code you have shown.

Are you sure you open the assistant editor for File's Owner (you can choose it if you open Placeholders in the left side of the xib editor)?

Anyway, if something is going wrong in your project, you are mistaking something in your xib file, which we cannot see.
Read the article again and again and again, carefully, and follow all the instructions written in it.

As long as the .xib is set to UIView

Please check again, the Custom Class of the main View is set to UIView (reset to its default), and the Custom Class of the File's Owner is set to HeaderView.
Seems to be working now! This is great, thanks :)

Seems to be working now! This is great, thanks :)

Oh, you have made it. Congratulations.

Anyway, to make this sort of hack working, there may be some unusual settings and we need to be careful about it.

As a side note though, is it possible to add a back button to a .xib like this? What I have used previously doesn't work:  Cannot find 'dismiss' in scope


Code Block
@IBAction func dismissVC(_ sender: Any) {
         dismiss(animated: true, completion: nil)
    }

Cannot find 'dismiss' in scope

dismiss(animated:completion:) is a method defined in UIViewController. Your HeaderView is a subclass of UIView, so dismiss(animated:completion:) is not available inside the instance method of HeaderView.

You may need to define a custom action in your HeaderView, and then connect the action to a method of the view controller.
And then call dismiss(animated:completion:) inside the method.
But, sorry, I have not tried that before and have no sample code to show to you.
Maybe I should be using a navigation bar instead... I had to give it up last time because I wasn't able to put in UILabels in the header. I want to put in a back button, title, and UILabel with some status text. I'll look up some tutorials on navigation bars
Problems using classes for reusable headers
 
 
Q