Please note, this blog entry is from a previous course. You might want to check out the current one.
Upon rotation (or any bounds change), maintain the origin of your graph with respect to the center of your graphing view rather than with respect to the upper left corner.
The easy way would be to define the origin not relative to the left top corner, but to the center … But then our API would be different to the axis drawer, and if somebody already would have been using our API we would break their code …
Thus we keep the public origin property relative to the left top corner, but store it via a new private property relative to the center:
private var originRelativeToCenter: CGPoint = CGPoint() { didSet { setNeedsDisplay() } }
… and we change the origin property to be a computed one, deriving and setting its value via the new variable:
var origin: CGPoint { get { var origin = originRelativeToCenter origin.x += center.x origin.y += center.y return origin } set { var origin = newValue origin.x += center.x origin.y += center.y originRelativeToCenter = origin } }
This way we can even remove the reset-origin code. However, when the origin gets set before the center of the graph has received it’s correct value depending on the current device our code does not work properly. e.g. when switching back and forth from the calculator view to the graph view, the origin will skip.
As work around we skip the center adjustments when the geometry is not ready and catch up if it is:
private var geometryReady = false var origin: CGPoint { get { var origin = originRelativeToCenter if geometryReady { origin.x += center.x origin.y += center.y } return origin } set { var origin = newValue if geometryReady { origin.x -= center.x origin.y -= center.y } originRelativeToCenter = origin } } override func drawRect(rect: CGRect) { if !geometryReady && originRelativeToCenter != CGPointZero { var originHelper = origin geometryReady = true origin = originHelper } ... }
The complete code for the extra task #4 is available on GitHub.