I've appended the code for GameController.swift below. To actually reproduce the bug, you need an image file Card Back.png in the project. It has a resolution of 672x1038 pixels.
- Create a new iOS Swift Single View Application project.
- Add Game Controller.swift and Card Back.png to it.
- In IB, change the view controller class to GameController.
- Drag a second view controller into the story board and change its class to GameController, too.
- Create a seque from the first to the second scene. (I added a Tap Gesture Recognizer to the first scene and created a Present Modally seque to the second scene; a Push/Show seque will give the same result.)
- Run the app on the iPhone simulator. You will see a 5x6 grid of copies of the Card Back image.
- Tap anywhere on the view to present the second scene.You will see part of one really big card back image.
- If you do Debug > View Debugging > Capture View Hierarchy and click Show Clipped Content, you will see that there is actually a grid of 672x1038 image views, which obviously does not fit on the screen.
GameController.swift
import UIKit
class GameController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
/
self.view.translatesAutoresizingMaskIntoConstraints = false
createCardGrid(self.view)
}
func createCardGrid(grid: UIView) {
let rows = 5
let cols = 6
/*
Create a view for each card.
*/
let cards = (0..<rows*cols).map { c -> UIImageView in
let card = UIImageView(image: UIImage(named: "Card Back"))
card.contentMode = .ScaleAspectFit
card.translatesAutoresizingMaskIntoConstraints = false
grid.addSubview(card)
return card
}
var constraints: [NSLayoutConstraint] = []
/*
Constrain all the card views to have the same heights and widths.
*/
let card0 = cards.first!
constraints += cards.dropFirst().flatMap { card in [
card.widthAnchor.constraintEqualToAnchor(card0.widthAnchor),
card.heightAnchor.constraintEqualToAnchor(card0.heightAnchor),
] }
/*
Vertical guides will manage the vertical spacing between rows. Guide [0] is between the top of
the view and the first row, guides 1..<numRows are between rows, and guide [numRows] is between
the last row and the bottom of the view.
*/
let verticalGuides = (0 ... rows).map { _ -> UILayoutGuide in
let guide = UILayoutGuide()
grid.addLayoutGuide(guide)
return guide
}
/*
Inter-row spacing should be 1/10 of the card height.
*/
constraints += verticalGuides.flatMap { guide in [
guide.widthAnchor.constraintEqualToAnchor(grid.widthAnchor),
guide.heightAnchor.constraintEqualToAnchor(card0.heightAnchor, multiplier: 0.10)
] }
/*
Horizontal guides will manage the horizontal spacing between columns. Guide [0] is between the left
edge of the view and the first column, guides 1..<numCols are between columns, and guide [numCols]
is between the last column and the right edge of the view.
*/
let horizontalGuides = (0 ... cols).map { _ -> UILayoutGuide in
let guide = UILayoutGuide()
grid.addLayoutGuide(guide)
return guide
}
/*
Inter-column spacing should be 1/10 of the card width.
*/
constraints += horizontalGuides.flatMap { guide in [
guide.heightAnchor.constraintEqualToAnchor(grid.heightAnchor),
guide.widthAnchor.constraintEqualToAnchor(card0.widthAnchor, multiplier: 0.10)
] }
/*
Attach the outer guides to the view edges.
*/
constraints += [
verticalGuides[0].topAnchor.constraintEqualToAnchor(grid.topAnchor),
verticalGuides[rows].bottomAnchor.constraintEqualToAnchor(grid.bottomAnchor),
horizontalGuides[0].leftAnchor.constraintEqualToAnchor(grid.leftAnchor),
horizontalGuides[cols].rightAnchor.constraintEqualToAnchor(grid.rightAnchor),
]
/*
Attach the cards to their adjacent guides. (Lay out the list of cards in the grid in
row-major order.)
*/
constraints += (0 ..< rows).flatMap { r in
(0 ..< cols).flatMap { c in [
cards[r * cols + c].topAnchor.constraintEqualToAnchor(verticalGuides[r].bottomAnchor),
cards[r * cols + c].bottomAnchor.constraintEqualToAnchor(verticalGuides[r+1].topAnchor),
cards[r * cols + c].leftAnchor.constraintEqualToAnchor(horizontalGuides[c].rightAnchor),
cards[r * cols + c].rightAnchor.constraintEqualToAnchor(horizontalGuides[c+1].leftAnchor),
]
}
}
NSLayoutConstraint.activateConstraints(constraints)
}
}