简体   繁体   中英

How does initializing UIView subclass properties affect superview's center?

I'm having a problem with the graphOrigin property in my UIView subclass. When I defined graphOrigin as a computed variable, it convert's the superview's center point to this view's center point and displays the graph in the center of the screen. This does not happen when the variable isn't computed. See code and screenshot for the working case:

class GraphX_YCoordinateView: UIView {

    var graphOrigin: CGPoint {
        return convertPoint(center, fromView: superview)
    }

    @IBInspectable var scale: CGFloat = 50 {
        didSet {
            setNeedsDisplay()
        }
    }

    override func drawRect(rect: CGRect) {

        // Draw X-Y axes in the view
        let axesDrawer = AxesDrawer(contentScaleFactor: contentScaleFactor)
        axesDrawer.drawAxesInRect(bounds, origin: graphOrigin, pointsPerUnit: scale)
    }

}

图形居中

AxesDrawer is a class that draws axes in the current view, here is the method signature for drawAxesInRect:

drawAxesInRect(bounds: CGRect, origin: CGPoint, pointsPerUnit: CGFloat)

And here is the code and screenshot for the case that doesn't work:

class GraphX_YCoordinateView: UIView {

    var graphOrigin: CGPoint! {
        didSet {
            setNeedsDisplay()
        }
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        graphOrigin = convertPoint(center, fromView: superview)
    }

    @IBInspectable var scale: CGFloat = 50 {
        didSet {
            setNeedsDisplay()
        }
    }

    override func drawRect(rect: CGRect) {

        // Draw X-Y axes
        let axesDrawer = AxesDrawer(contentScaleFactor: contentScaleFactor)
        axesDrawer.drawAxesInRect(bounds, origin: graphOrigin, pointsPerUnit: scale)
    }
}

图表未居中

So literally all I changed was initializing the graphOrigin property in place and computing it in the initializer. I didn't touch the StoryBoard at all while editing this code.

I tried initializing the variable inline:

var graphOrigin = convertPoint(center, fromView: superview)

But this wasn't allowed because the implicit self is not initialized when properties are computed.

Can anyone explain why the superview's center seems to change location depending on how the variable is initialized?

This function

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    graphOrigin = convertPoint(center, fromView: superview)
}

means that you are loading view from xib, and at this time the view dimension is 600:600 (look at your xib). So that your graphOrigin = 300:300 . This is why you see the second picture.

To fix that problem, you should compute the graphOrigin after the view finish layout in viewDidLayout .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM