1

I'm practicing awakeFromNib.

I have a single UIView in Main.storyboard. This UIView inherit class CardView.

Codes are below

class ViewController: UIViewController {

    @IBOutlet weak var cardView: CardView!

}

And I have a CardView.xib. In, CardView.xib, there's a default single UIView which inherits a class CardView. And inside this UIView, there's the other single view which inherits a class CardContentView. And Of course, I have a CardView.swift which have class CardView.

Codes are below

class CardView: UIView {

    @IBOutlet weak var cardContentView: CardContentView!

    override func awakeFromNib() {
        cardContentView.layer.cornerRadius = 16
    }
}

And I have a CardContentView.xib. In, CardContentView.xib, there's a default single UIView which inherits a default class UIView. And Of course, I have a CardContentView.swift which have class CardContentView.

Codes are below

class CardContentView: UIView {

    @IBOutlet var backgroundView: UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit(){
        Bundle.main.loadNibNamed("CardContentView", owner: self, options: nil)
        self.addSubview(backgroundView)
    }

}

Yes, I want to show the CardContentView to cardView in ViewController through class CardView.

But when I run, the error pops in class CardView

The error line is on the func awakeFromNib

The specific line is cardContentView.layer.cornerRadius = 16.

The error message is Unexpectedly found nil while unwrapping an Optional value. Especially, cardContentView = nil.

I don't know why cardContentView = nil.

I linked cardContentView in Xib board to class CardView in CardView.swift.

And how should I modify the code to run this?

Thank you!

Swifty
  • 839
  • 2
  • 15
  • 40
Hoo
  • 135
  • 13

1 Answers1

0

First of all, you need to connect the cardView outlet in the main storyboard, and of course, you've added a view in your ViewController. Then in your CardView class, you have to instantiate cardContentView outlet, because in CardView.xib you do not have any reference to cardContentView. Make sure that you've connected backgroundView outlet in CardContentView.xib.

class CardView: UIView {

    @IBOutlet weak var cardContentView: CardContentView!

    override func awakeFromNib() {
        super.awakeFromNib()
        cardContentView = Bundle.main.loadNibNamed("CardContentView", owner: self, options: nil)!.first as! CardContentView
        self.addSubview(cardContentView)
        cardContentView.layer.cornerRadius = 16

        //you can also get access to the subviews of cardContentView
        //cardContentView.backgroundView.backgroundColor = .red
    }
}


class CardContentView: UIView {

    @IBOutlet var backgroundView: UIView!

    override func awakeFromNib() {
        backgroundView.backgroundColor = .yellow
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        //commonInit()
    } 

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        //commonInit()
    }

    private func commonInit() {
    }
}
Hasti Ranjkesh
  • 643
  • 10
  • 26
  • Thank you for your comment. I tried based on your advice, but 'this class is not key value coding-compliant for the key backgroundView.' pops. – Hoo Oct 21 '18 at 09:05
  • @Hoo you can access the subviews of cardContentView in CardView class. I edited the answer, for example, I changed the background color of the backgroundView. Then you don't need to instantiate the backgroundView in the commonInit method of CardContentView. – Hasti Ranjkesh Oct 21 '18 at 09:10
  • Thank you for your reply. But, what I want is using pure backgroundView in CardContentView. I want to implement it to CardView nothing Changed. – Hoo Oct 21 '18 at 09:29
  • @Hoo you can override awakeFromNib method in CardContentView class. without instantiating backgroundView, you can access to it. See the edited answer. – Hasti Ranjkesh Oct 21 '18 at 09:37