Here is what I am trying to do:
class ViewController: UIViewController {
let screenRect: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenRect.w
Its not possible to access self before initialisation process gets completed, therefore its giving error.
What probably happens is that during instantiation and initialization it's not guaranteed that properties are initialized in the same order as you have defined them in the code, so you cannot initialize a property with a value retrieved from another property.
My suggestion is to move the property initializations in the init()
method.
Addendum 1: as suggested by @Yatheesha, it's correct to say that self
is not available until all properties have been initialized - see "Two-Phase Initialization" paragraph in the swift book, under "Initialization"
In this line (as well as in the ones after it):
let screenWidth = screenRect.width;
you are implicitly using self
.
So the correct way is to use init()
as follows:
let screenRect: CGRect
let screenWidth: NSNumber
let screenHeight: NSNumber
let screenX: NSNumber
let screenY: NSNumber
init(coder aDecoder: NSCoder!) {
let bounds = UIScreen.mainScreen().bounds
screenRect = bounds
screenWidth = bounds.width
screenHeight = bounds.height
screenX = bounds.origin.x
screenY = bounds.origin.y
super.init(coder:aDecoder)
}
Of course if there is more than one designated init()
, you have to replicate that code on each. In that case it might be better to use @Andy's approach, using computed properties, if you prefer to avoid code duplication.
Addendum 2
Another obvious way (and probably the best one) is to avoid using self
at all:
let screenRect: CGRect = UIScreen.mainScreen().bounds
let screenWidth = UIScreen.mainScreen().bounds.width;
let screenHeight = UIScreen.mainScreen().bounds.height;
let screenX = UIScreen.mainScreen().bounds.origin.x
let screenY = UIScreen.mainScreen().bounds.origin.y
The consts do not know about the other global consts because they are not initialized at this point. What you could do though is to use computed properties:
class ViewController: UIViewController {
var screenRect: CGRect { return UIScreen.mainScreen().bounds }
var screenWidth: CGFloat { return self.screenRect.origin.x }
}
This only works with vars, due to the nature of it. This should be considered depending on the use case. If you have to call it often, it might not be the wisest way in regards to performance.