【问题标题】:Why is frame width of the view alway 600 by 600 with autolayout为什么使用自动布局的视图的框架宽度总是 600 x 600
【发布时间】:2015-07-25 13:05:49
【问题描述】:

我正在制作一个基本的扫雷应用程序,用于快速练习/娱乐。我想让它的大小(10 块宽)适应任何 iOS 屏幕。

为此,我通过获取 tileContainer view.frame.width 和 /10 来设置每个图块的大小。

我的问题是 tileContainer 视图设置为 600,无论如何。在我的 Storyboard 上,我将 tileContainer 设置为等于 View Container 的宽度,通过 CTR 单击并拖动到视图并选择相等的宽度。这将 tileContainer 的宽度设置为 600,无论我在什么设备上进行测试。 (这是我的问题,宽度应该根据屏幕宽度而不是恒定的 600 而变化)

有谁知道我如何获得适当的屏幕宽度,而不管它在什么设备上使用?

【问题讨论】:

  • “在我的 Storyboard 上,我将 tileContainer 设置为等于 View Container 的宽度,通过 CTR 单击并拖动到视图并选择相等的宽度。”这听起来已经是正确的做法了。
  • 在视觉上它工作得很好,在视觉上正确设置了视图宽度,但是在代码中调用 tileContainer.frame.width 将始终返回 600。如果我在 iPhone 6 上进行测试,可调整大小iPhone,iPhone 5s。总是返回 600
  • 因为它是 600,所以瓷砖宽度设置为 60,它们很快就会离开屏幕

标签: ios swift storyboard autolayout


【解决方案1】:

当您使用自动布局时,子视图在viewDidLayoutSubviews 函数之后布局。因此,如果您在此之前调用 tileContainer.frame.size,例如在 viewDidLoad 中,它将始终为 600 x 600(这是故事板中的默认大小)。

viewDidLayoutSubviews:调用以通知视图控制器其视图刚刚布置了其子视图。 reference

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    print(tileContainer.frame.size); // This is actual size you are looking for
}

【讨论】:

  • 谢谢,这很有意义并回答了我的问题。您知道将被调用的函数或在加载所有内容后等待执行代码的方法吗?因为 viewDidLayoutSubviews() 被我调用了两次。
  • 你好@EvanNudd,是的,这个函数会被多次调用。有关说明,请参阅此 post。但我认为没关系。例如,当您旋转设备时,宽度肯定会发生变化,您需要相应地更改磁贴。
  • 我猜你想创建一些子视图作为瓷砖?如果是这种情况,您可以做的是将 alloc init 代码放在 viewDidLoad 中,然后在 viewDidLayoutSubviews 中放置一些重新定位/调整大小的代码。
  • 另一个建议是约束。您也可以在代码中设置常量。使用自动布局的巨大好处是您不必担心设备方向、不同设备屏幕尺寸等的布局。您可以了解有关以编程方式使用自动布局的更多信息here
  • @YuchenZhong 我不知道为什么或如何,但它现在没有发生。图像现在可以正常显示
【解决方案2】:

简答:UIScreen.mainScreen().bounds.size.width 总是返回屏幕的宽度。

长答案:听起来您正在使用带有大小类的自动布局。您可以仅使用约束来完成这一切。您可以设置从磁贴到容器的比例宽度和高度约束,以使磁贴为容器宽度和高度的 10%。然后,您可以将所有其他图块设置为与该图块具有相同的宽度和高度。然后,使用约束将它们定位在网格中。

使用自动布局的另一种策略是将单元格之间的间距设置为 0,并且不限制宽度和高度。如果你有 10 个单元格,单元格之间的间距为 0,并且前后单元格与容器之间的间距为 0,那么它们将自动占据容器宽度的 1/10。

附加说明,如果使用尺寸类/自动布局,在布局子视图之前不会正确设置视图大小,所以如果你试图在 viewDidLoad 中做这个宽度的东西,例如,宽度仍然是宽度任何任何尺寸类别 (600)。

【讨论】:

    【解决方案3】:

    虽然接受的答案是正确答案,但我想我至少可以说您可以在点击viewDidAppear: 之前强制视图自行绘制。

    您也可以在viewDidLoad: 中致电:

    view.setNeedsLayout()
    view.layoutIfNeeded()

    或者如果你从“外部”创建它:

    let vc = UIViewController()
    let _ = vc.view

    let vc = UIViewController()
    vc.view.setNeedsLayout()
    vc.view.layoutIfNeeded()

    【讨论】:

    • viewDidLoad 中添加view.setNeedsLayout()view.layoutIfNeeded() 对我有用。
    • 仅添加 view.layoutIfNeeded() 也对我有用,谢谢。
    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2014-11-10
    • 2011-07-12
    相关资源
    最近更新 更多