Search code examples
iosswiftclassobjectinstantiation

Instantiating a class and using properties makes app crash


I'm building a keyboard extension.
In my program I have a view controller(1) and a view(2) class which I use for a xib file .

1)

class KeyboardViewController: UIInputViewController {

override func viewDidLoad() {
        super.viewDidLoad()
        let nib = UINib(nibName: "view1", bundle: nil)
        let objects = nib.instantiate(withOwner: self, options: nil)
        view = objects[0] as? UIView
}
class View1: UIView {  

@IBOutlet weak var someLabel: UILabel!
@IBOutlet weak var someButton: UIButton!
}  
 

I wanted to instantiate the view class inside of my view controller so, following apple's documentation I did this:

class KeyboardViewController: UIInputViewController {
    let v1 = View1()
    let v2 = View2()
}

The problem is that whenever I try to call inside of my view did load something like:

v1.someLabel.text = "something"

and I run my app, for some reasons it doesn't work and eventually crashes.

Important things: the views are connected to two different .xib files and I'm working on a custom keyboard extension.

I'm sure I'm missing something in the instantiation but I can't find out what it is, I see other developers on git hub doing exactly the same as I do but running their apps gives no problem... So what am I missing out? If you can please send me more documentation about it as well...

Edit:
In both my view classes I'm doing the following to initialize them:

class View1: UIView {  
@IBOutlet weak var someLabel: UILabel!
@IBOutlet weak var someButton: UIButton!
  init(label: UILabel, button: UIButton) {
        self.someLabel = label
        self.someButton = button
        super.init(frame: CGRect(x: 0, y: 0, width: 330, height: 200))
    }

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

But then in my main view controller, when i call let v1 = View1(), it becomes:

let v1 = View1(coder: NSCoder)  

And I'm having a hard time figuring out what to put in the parameter field


Solution

  • I found a solution by myself:

    1. Go to your xib file, in the file's owner section set the custom class on View1; As per the view section, set the custom class to UIView;
    2. In your class View1: UIView add a view outlet from your xib file ie:
    @IBOutlet var view: UIView!
    
    1. Paste this in your class View1: 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("view1", owner: self, options: nil)
            addSubview(view)
            view.frame = self.bounds
            view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
           //Add any other setup here
        }
    
    
    1. Now create another xib file, make sure it's file's Owner is KeyboardViewController. Add an UIView to it and make sure its class is of type View1.

    2. Now go to class KeyboardViewController: UIInputViewController and link the view of type View1 in your code. Right under it write weak var v : View1!

    3. In viewDidLoad()you can eventually write view = View1()

    You're done!