UIStackView 未按预期显示

Posted

技术标签:

【中文标题】UIStackView 未按预期显示【英文标题】:UIStackView not showing as expected 【发布时间】:2018-10-13 07:45:49 【问题描述】:

我想在我的应用中添加一个UIStackView 的登录按钮,所以我添加了以下代码:

override func viewDidLayoutSubviews()
    
        super.viewDidLayoutSubviews()


        SignInButtonsStackView.center.x = self.view.center.x
        SignInButtonsStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10)
        SignInButtonsStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 10)
        SignInButtonsStackView.spacing = 5


        SignInButtonsStackView.addArrangedSubview(FacebookSignInButton)
        SignInButtonsStackView.addArrangedSubview(GoogleSignInButton)

    

我先设置UIStackView 的约束,然后再添加按钮。

我的目标是将来能够添加更多登录按钮,同时添加最少的代码。

这就是我得到的:

不仅宽度不一样,而且高度也乱了。

如何确保 UIStackView 中的所有项目都具有相同的宽度、高度和间距?如何修复此视图以使其看起来不错?

编辑

我在调试窗口中有这个:

"<NSLayoutConstraint:0x600000288700 UILayoutGuide:0x6000007b0760'UIViewSafeAreaLayoutGuide'.bottom == UIStackView:0x7f9b04d15420.bottom + 187   (active)>",
    "<NSLayoutConstraint:0x600000288ac0 V:|-(499)-[UIStackView:0x7f9b04d15420]   (active, names: '|':UIView:0x7f9b04d166e0 )>",
    "<NSLayoutConstraint:0x60c000290f40 GIDSignInButton.height == 10   (active, names: GIDSignInButton:0x7f9b04d076e0 )>",
    "<NSLayoutConstraint:0x60800028cd50 'UISV-canvas-connection' V:[GIDSignInButton]-(0)-|   (active, names: GIDSignInButton:0x7f9b04d076e0, '|':UIStackView:0x7f9b04d15420 )>",
    "<NSLayoutConstraint:0x60c00028bb80 'UISV-canvas-connection' UIStackView:0x7f9b04d15420.top == FBSDKLoginButton:0x7f9b04d0a4d0'Continue with Facebook'.top   (active)>",
    "<NSLayoutConstraint:0x60c00028ad20 'UISV-fill-equally' GIDSignInButton.height == FBSDKLoginButton:0x7f9b04d0a4d0'Continue with Facebook'.height   (active, names: GIDSignInButton:0x7f9b04d076e0 )>",
    "<NSLayoutConstraint:0x60c000288610 'UISV-spacing' V:[FBSDKLoginButton:0x7f9b04d0a4d0'Continue with Facebook']-(5)-[GIDSignInButton]   (active, names: GIDSignInButton:0x7f9b04d076e0 )>",
    "<NSLayoutConstraint:0x60800028d1b0 'UIView-Encapsulated-Layout-Height' UIView:0x7f9b04d166e0.height == 736   (active)>",
    "<NSLayoutConstraint:0x600000288840 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000007b0760'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x7f9b04d166e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60c000290f40 GIDSignInButton.height == 10   (active, names: GIDSignInButton:0x7f9b04d076e0 )>

【问题讨论】:

试试 SignInButtonsStackView.alignment = .fill 我添加了 .fill ,这对视图没有任何影响... SignInButtonsStackView.center.x = self.view.center.x 不是约束。您还在每个布局之后添加新的约束,一段时间后您将得到数十个重复的约束。 不要在viewDidLayoutSubviews中做这样的事情! 【参考方案1】:

您不需要设置UIStackView 的高度限制。只需在UIStackView 中设置UIButton's 的高度约束并在UIStackView 中分配到“等间距”。

【讨论】:

我没有为 UIStackView 设置高度限制。只有中心,领先和落后。你将如何继续按照你说的去做? 正如我所说,您需要为添加到 UIStackView 中的每个 UIButton 设置高度限制。 我添加了 FacebookSignInButton.heightAnchor.constraint(equalToConstant: 10).isActive = true (与 GoogleSignInButton 相同),没有任何改变...【参考方案2】:

我建议您添加SignInButtonsStackView.distribution = .fillEqually 以获得相同的按钮高度和SignInButtonsStackView.alignment = .fill 以获得相同的宽度。

不幸的是,按钮的行为取决于其视图可能具有的内部约束。我建议检查控制台是否有任何与“无法满足的约束”相关的日志(为UIViewAlertForUnsatisfiableConstraints 设置符号断点可能很有用https://staxmanade.com/2015/06/debugging-ios-autolayout-issues/)。

【讨论】:

@Ofri 可以在日志控制台中看到任何问题吗?你有什么不可满足的约束错误吗? 中列出的 UIView 上的 UIConstraintBasedLayoutDebugging 类别中的方法也可能会有所帮助。 2018-10-13 06:03:40.341356-0700 App[8030:168796] [LayoutConstraints] 无法同时满足约束。 好的,你能看出哪些约束是不可能满足的吗?两个按钮都可能有一些内部约束,因此不可能同时创建相同的高度和相同的宽度。您应该在调试器控制台中找到更多信息。 也许这些? ( "<0x6000002915d0 v: abir><0x600000292ac0 v: abir><0x600000292ac0 v: abir>

以上是关于UIStackView 未按预期显示的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 未按预期显示约束

为啥模态演示表单未按预期显示?

阅读电子邮件的 html 模板未按预期显示

CollectionView 未按预期显示 3 列

嵌入在 UITableView 中的 UICollectionView 中的 UICollectionViewCells 未按预期显示

JSON 中的数据对象未按预期显示