I am currently getting to grips with UIKit
and trying to build a simple game to do so. The first part I am struggling to understanding is auto layout, the necessary constraints and their behaviour, as well as view hierarchy.
Here is a basic UIViewController
that is simply trying to place a game board (UIImageView
) onto its root view.
class GameView {
var gameBoard: UIImageView = UIImageView(image: UIImage(named: "grid"))
}
class SinglePlayerGameViewController: UIViewController {
var gameModel: GameModel = GameModel()
var gameView: GameView = GameView()
override func viewDidLoad() {
super.viewDidLoad()
self.setUpGameBoard()
//self.startGame()
}
private func setUpGameBoard() -> Void {
print("screen size", UIScreen.main.bounds.size)
self.gameView.gameBoard.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.gameView.gameBoard)
self.gameView.gameBoard.contentMode = .scaleAspectFit
self.gameView.gameBoard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
print("vc center X", self.view.center.x)
print("gb center X", self.gameView.gameBoard.center.x)
self.gameView.gameBoard.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
print("vc center Y", self.view.center.y)
print("gb center Y", self.gameView.gameBoard.center.y)
self.gameView.gameBoard.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9).isActive = true
print("vc width bounds", self.view.bounds.size.width)
print("vc width frame", self.view.frame.size.width)
print("gb width bounds", self.gameView.gameBoard.bounds.size.width)
print("gb width frame", self.gameView.gameBoard.bounds.size.width)
}
}
The output of the print statements below is as follows:
screen size (428.0, 926.0)
vc center X 214.0
gb center X 375.0
vc center Y 463.0
gb center Y 500.0
vc width bounds 428.0
vc width frame 428.0
gb width bounds 750.0
gb width frame 750.0
What confuses me is the following:
According to the quick help in Xcode, the centerXAnchor is defined as:
A layout anchor representing the horizontal center of the view’s frame
. So I am struggling to understand why the output for center x-coordinates for the parent view and the game board is different? The same thing goes for the center y-coordinate.The widthAnchor is defined as:
A layout anchor representing the width of the view’s frame.
. So I would think that applying the multiplier of .9 would result in the width of my game board being exactly 90% of the parent view's frame, but that doesn't seem to be the case here and I can't really see why.
The funny thing is that the simulator is still displaying it properly, like so:
If there is anyone that could shed some light on this, I would very much appreciate it!
Thanks
CodePudding user response:
Because you are doing your print
statements in viewDidLoad
which is before your autolayout constraints have taken effect. You can create constraints there, but they are not applied fully until layout time. Move all the print
statements into viewDidLayoutSubviews
, keeping everything else the same, and you will get the results you expect.