Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to initialize in Swift?

I have a very general question about the Initialization in Swift. Unlike in Objective C it's now possible to call the init() directly at the declaration outside of my functions: e.g.

class ViewController: UIViewController {
    let myView: UIView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        myView.frame = getFrame()
        myView.backgroundColor = UIColor.redColor()
        self.view.addSubview(myView)

    }

    func getFrame() -> CGRect {
        return CGRectMake(0, 0, 100, 100)
    }
}

In Objective C I would have done the initialization in my function.

But what if I want to call an Initializer with parameters which are not set yet? e.g. I want to init with a frame which is being calculated in a func()

class ViewController: UIViewController {

    //THIS IS NOT WOKRING
    let myView: UIView = UIView(frame: getFrame())

    override func viewDidLoad() {
        super.viewDidLoad()

        myView.backgroundColor = UIColor.redColor()
        self.view.addSubview(myView)

    }

    func getFrame() -> CGRect {
        return CGRectMake(0, 0, 100, 100)
    }
}

I don't wanna do my initializations at two different places in the Code. Is there any general pattern for the initializations?

like image 648
Michael Avatar asked Sep 29 '22 05:09

Michael


1 Answers

So your options for initialisation in swift are numerous. With your current example you cannot use the method getFrame() yet because you do not yet have a reference to self as the ViewController has not get been initialised. Instead you could use:

let myView: UIView = UIView(frame: CGRectMake(0, 0, 100, 100))

As this does not require the reference to self. Alternatively you could lazy instantiation which will get run after self is available (this can only be used with var not let:

lazy var myView: UIView = {
    return UIView(frame:self.getFrame())
}()

To answer your question, when using UIKit class where you often don't have control over their instantiation you can keep doing it the same was as you were in objective c and use implicitly unwrapped optionals (to prevent you having to use a ! or ? every time you instantiate a variable, e.g.:

var myView: UIView!

override func viewDidLoad(){
    super.viewDidLoad();

    myView = UIView(frame:getFrame())
}

This however does not work with let constants, as they need to be assigned either immediately or in the constructor of the object. Hope this helps.

like image 125
Bulwinkel Avatar answered Oct 05 '22 07:10

Bulwinkel