自动布局,布局约束产生令人费解的结果 UIKit Swift 5

Posted

技术标签:

【中文标题】自动布局,布局约束产生令人费解的结果 UIKit Swift 5【英文标题】:Auto-Layout, layout constraints producing puzzling results UIKit Swift 5 【发布时间】:2021-12-30 20:04:38 【问题描述】:

我目前正在掌握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.。所以我认为应用 0.9 的乘数会导致我的游戏板的宽度正好是父视图框架的 90%,但这里似乎不是这种情况,我真的不明白为什么。

有趣的是模拟器仍然可以正常显示,像这样:

如果有人能对此有所了解,我将不胜感激!

谢谢

【问题讨论】:

【参考方案1】:

因为您在viewDidLoad 中执行print 语句,这是您的自动布局约束生效之前。您可以在此处创建约束,但直到布局时间它们才完全应用。将所有print 语句移动到viewDidLayoutSubviews 中,保持其他所有内容不变,您将获得预期的结果。

【讨论】:

谢谢你,你说得对!这让我想到了一个后续问题:如果视图是在“运行时”添加的,例如在游戏中产生“敌人”,你还能对它们应用约束并让它们在屏幕上正确布局吗? (目前无法正确实现)。 如果您还有其他问题(听起来确实如此),请按下按钮并提出问题! :)

以上是关于自动布局,布局约束产生令人费解的结果 UIKit Swift 5的主要内容,如果未能解决你的问题,请参考以下文章

Android 屏幕适配屏幕适配通用解决方案 ⑥ ( 约束布局 ConstraintLayout 百分比布局方案 | 将设计稿尺寸自动转为约束布局百分比标签属性 | 将输出结果设置到组件标签中 )

Android 屏幕适配屏幕适配通用解决方案 ⑥ ( 约束布局 ConstraintLayout 百分比布局方案 | 将设计稿尺寸自动转为约束布局百分比标签属性 | 将输出结果设置到组件标签中 )

iOS9之UIStackView体验,无需任何约束,这才是真正的自动布局,快到不能呼吸

我们可以在 iOS 6 自动布局生成的帧上产生 CGRectIntegral 的效果吗?

为啥自动布局不能产生一致的结果?

UIKit框架屏幕适配