自动布局,布局约束产生令人费解的结果 UIKit Swift 5
Auto-Layout, layout constraints producing puzzling results UIKit Swift 5
我目前正在掌握 UIKit
并尝试为此构建一个简单的游戏。我很难理解的第一部分是自动布局、必要的约束及其行为,以及视图层次结构。
这是一个基本的 UIViewController
,它只是尝试将游戏板 (UIImageView
) 放置到其根视图上。
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)
}
}
下面打印语句的输出如下:
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
让我感到困惑的是以下内容:
根据Xcode中的快速帮助,centerXAnchor定义为:A layout anchor representing the horizontal center of the view’s frame
。所以我很难理解为什么父视图和游戏板的中心 x 坐标输出不同?中心 y 坐标也是如此。
widthAnchor 定义为:A layout anchor representing the width of the view’s frame.
。所以我认为应用 .9 的乘数会导致我的游戏板的宽度正好是父视图框架的 90%,但这里似乎不是这种情况,我真的不明白为什么。
有趣的是,模拟器还是可以正常显示的,像这样:
如果有人可以对此有所了解,我将不胜感激!
谢谢
因为您在 viewDidLoad
中执行 print
语句,即 在 您的自动布局约束生效之前。您可以在那里 创建 约束,但在布局时间之前它们不会 应用 完全。将所有 print
语句移动到 viewDidLayoutSubviews
,保持其他所有内容不变,您将获得预期的结果。
我目前正在掌握 UIKit
并尝试为此构建一个简单的游戏。我很难理解的第一部分是自动布局、必要的约束及其行为,以及视图层次结构。
这是一个基本的 UIViewController
,它只是尝试将游戏板 (UIImageView
) 放置到其根视图上。
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)
}
}
下面打印语句的输出如下:
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
让我感到困惑的是以下内容:
根据Xcode中的快速帮助,centerXAnchor定义为:
A layout anchor representing the horizontal center of the view’s frame
。所以我很难理解为什么父视图和游戏板的中心 x 坐标输出不同?中心 y 坐标也是如此。widthAnchor 定义为:
A layout anchor representing the width of the view’s frame.
。所以我认为应用 .9 的乘数会导致我的游戏板的宽度正好是父视图框架的 90%,但这里似乎不是这种情况,我真的不明白为什么。
有趣的是,模拟器还是可以正常显示的,像这样:
如果有人可以对此有所了解,我将不胜感激!
谢谢
因为您在 viewDidLoad
中执行 print
语句,即 在 您的自动布局约束生效之前。您可以在那里 创建 约束,但在布局时间之前它们不会 应用 完全。将所有 print
语句移动到 viewDidLayoutSubviews
,保持其他所有内容不变,您将获得预期的结果。