Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use instance member within property initializer

Tags:

ios

swift3

I have written a custom UIView and I found a strange problem. I think this is related to a very fundamental concept but I just do not understand it, sigh.....

class ArrowView: UIView {

    override func draw(_ rect: CGRect) {

        let arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x:bounds.size.width/2,y:bounds.size.height/3), endPoint: CGPoint(x:bounds.size.width/2, y:bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)

        let fillColor = UIColor(red: 0.00, green: 0.59, blue: 1.0, alpha: 1.0)
        fillColor.setFill()
        arrowPath.fill()
    }
}

this code works fine but if I have grabbed this line out of the override draw function it does not compile. The error says I can not use the bounds property.

let arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x:bounds.size.width/2,y:bounds.size.height/3), endPoint: CGPoint(x:bounds.size.width/2, y:bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)

Cannot use instance member 'bounds' within property initializer; property initializers run before 'self' is available

I don not understand why I cannot use this bounds out of the func draw

like image 929
Billy Avatar asked Jul 31 '17 18:07

Billy


1 Answers

So if we decode the error message you can figure out whats wrong. It says property initializers run before self is available so we need to adjust what we're doing since our property depends on bounds which belongs to self. Lets try a lazy variable. You can't use bounds in a let because it doesn't exist when that property is created because it belongs to self. So at init self isn't complete yet. But if you use a lazy var, then self and its property bounds will be ready by the time you need it.

lazy var arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x: self.bounds.size.width/2,y: self.bounds.size.height/3), endPoint: CGPoint(x: self.bounds.size.width/2, y: self.bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)
like image 181
Ryan Poolos Avatar answered Nov 05 '22 07:11

Ryan Poolos