What I would like to achieve:
A rectangle (paper) of a given size which is draw inside a view. If it is larger than the view I would like it to be scrollable. If it is smaller than the view I would like it be centered.
A list of shapes should be drawn on top of this rectangle. If they are outside the rectangle they should not be clippd but be drawn anyway.
The scrollable area is only affected by the rect(paper) not by the shapes. So a shape outside the scrollable area does not need to be drawn.
I am using Swift2.0, auto layout and InterfaceBuilder
What I have now:
I have a custom CanvasView inside an NSScrollView.
I used this trick to center the CanvasView if the canvas size is smaller than the NSScrollView: https://stackoverflow.com/a/28154936/1533291
My CanvasView is defined like this:
class CanvasView : NSView {
var canvasSize = Vec2d(x: 100, y: 100) {
didSet {
invalidateintrinsiccontentsize()
}
}
var shapes : [MyShape] = []
override func drawRect(dirtyRect: NSRect) {
if let context = currentContext {
let offsetX = (bounds.width-CGFloat(canvasSize.x))/2.0
let offsetY = (bounds.height-CGFloat(canvasSize.y))/2.0
CGContextTranslateCTM(context, offsetX, offsetY)
CGContextSetRGBFillColor(context, 1, 1, 1, 1)
CGContextFillRect(context, CGRect(x:0,y:0, width: CGFloat(canvasSize.x), height: CGFloat(canvasSize.y)))
for shape in shapes {
shape.shape.render(context)
}
}
}
override var intrinsicContentSize : NSSize {
return NSSize(width: canvasSize.x, height: canvasSize.y)
}
}
So as you can see I draw everything centered inside the canvas view.
The problem is if one of the shapes is outside the canvas it get's clipped because drawRect can only draw inside the view's bounds.
Thats why I would like to stretch the CanvasView so it's width and height are alway equal to or greater than the size of the scrollview. But I do not know how to do it and I am not even sure if this is the most elegant approach.
Update: The answer I posted below does not work when the ScrollView is zoomable and the zoom factor is less than one. I this case the canvas is neither stretched to full size nor is it centred. I am still interested in a working solution for zoomable Scrollviews.