TiledImageView: dynamic resize to see all content w/o scroll

I am working through the book and currently working on the ImageTiling application. I have been trying unsuccessfully to get the TiledImageView to dynamically resize itself so that the entire matrix of images are displayed without the scroll view. I have only slightly modified the TileImageView (attached below)

– It only partly works: The window is the correct size, but the upper half of the window contains 2.5 rows of the image, while the bottom half of the window is blank.
– It seems kludgy. I am guessing there is a more elegant way to resize views dynamically.

Ultimately, I am trying to create matrix of images with controls to change the number of rows and columns. Once I can figure out how to resize things properly, then I should be able to add the controls.

I am hoping that somebody can give me an answer in english (as opposed to code) using Cocoa vocabulary so that I can study the reference material and come back for code help if needed. Preferably, I would like to learn how to control windows and views more programmatically so I can better understand what is happening behind the scenes of IB in terms of the window / view hierarchy.

Here are the changes that I made to the code from TiledImageView:
– Added an image to the project and used that as the image to tile
– Added two computed properties in order to get the size that the view should be, viewSizeX and viewSizeZ.
– Added awakeFromNib() thinking this should be the spot to change the size for the time being; I know I will need code to change the window & view size somewhere else as every time the user changes the # of rows and columns, the window and views need to resize.



class TiledImageView: NSView {

	var image: NSImage = NSImage(named: "red-128x128.png")!
	let columnCount = 5
	let rowCount = 5
	var viewSizeX: CGFloat {
		return self.image.size.width * CGFloat(columnCount)
	var viewSizeY: CGFloat {
		return self.image.size.height * CGFloat(rowCount)
	override func awakeFromNib() {
		// set window's content frame size
		var myContentFrame: NSRect = self.window!.contentView.frame
		myContentFrame.size = NSMakeSize(viewSizeX + 40.0, viewSizeY + 40.0)
		self.window!.contentView.window.setFrame(myContentFrame, display: true)
		// set view's frame size
		var myFrame: NSRect = self.frame
		myFrame.size = NSMakeSize(viewSizeX, viewSizeY)
		self.frame = myFrame
    override func drawRect(dirtyRect: NSRect) {
		// Drawing code here.
		for x in 0..<columnCount {
			for y in 0..<rowCount {
				let frame = frameForImageAtLogicalX(x, logicalY: y)
	override var intrinsicContentSize: NSSize {
		let furthestFrame = frameForImageAtLogicalX(columnCount - 1, logicalY: rowCount - 1)
		return NSSize(width: furthestFrame.maxX, height: furthestFrame.maxY)
	// MARK: - Drawing
	func frameForImageAtLogicalX(logicalX: Int, logicalY: Int) -> CGRect {
		let spacing = 0
		let width = 128
		let height = 128
		let x = (spacing + width) * logicalX
		let y = (spacing + height) * logicalY
		return CGRect(x: x, y: y, width: width, height: height)

You can do this by applying some Constraints to both the BorderedScrollView and its Clip View. Select MainWindowController.xib then select each view in turn and click on the Pin button in the lower right corner of the window. Pin all four edges of the view to its master view. Now when you run the program, its window should automatically be sized to show all the drawn images.