【问题标题】:set subview frames in layoutSubviews doesn't persist在 layoutSubviews 中设置子视图框架不会持续存在
【发布时间】:2015-04-17 15:37:04
【问题描述】:

我有一个自定义 UIView 子类,它抓取 layoutSubviews 中的所有子视图并根据一些自定义设置更改它们的布局/大小。

如果我以编程方式创建此视图,则一切正常,但是如果我将此 UIView 子类添加到情节提要并在情节提要中添加一些子视图,则布局更改似乎不会持续存在。

我可以看到以下使用断点的逻辑流程。

  1. VC 和自定义视图已初始化

  2. 调用了 VC viewDidLayoutSubviews。 (我在这里什么都不做,只是观察它是使用断点调用的)

  3. 自定义UIView,layoutSubviews被调用。

    override func layoutSubviews() {
        for subView in self.subviews {
            var subview = subView as! UIView
            var frame = subview.frame
            //some arbritary frame adjustments.
            frame.origin.x = 10; frame.origin.y = 50;
            subview.frame = frame
            subview.setNeedsLayout() //tried with and without this line with no difference.
        }
    }
    

    我可以看到框架正在调整,因为我在调整之前打印所有子视图,然后通过调试器再次打印。

    po self.subviews
    
  4. VC viewDidLayoutSubviews 再次被调用。但是,当我在这里打印子视图时,我可以看到它们又回到了原来的帧。

    po customView.subviews
    
  5. 出现视图且框架尚未调整。

如果我再次调用 layoutSubviews,子视图框架最终会调整,但是只有在视图出现之后才进行调整,这为时已晚。

override func viewDidLayoutSubviews() {
    customView?.layoutSubviews();
}

流程如下:

  1. VC & View 已初始化

  2. VC viewDidLayoutSubviews 被调用

  3. layoutSubviews 连续调用两次

  4. 视图出现并且子视图没有被重新调整,即使它们在通过调试器打印时位于 layoutSubviews 中。

  5. VC - 再次调用 viewDidLayoutSubviews

  6. layoutSubviews 再次被调用。

  7. 您可以看到子视图调整,但为时已晚,因为用户将能够看到子视图“跳转”到位。

关于我在这里缺少什么的任何想法?子视图框架肯定设置正确,但它们只是在视图出现之前被恢复。

我只是碰巧为此使用了 swift,但非常欢迎使用 Objective C 中的响应。

【问题讨论】:

  • 你有没有试过在setNeedsLayout之后立即拨打subview.layoutIfNeeded()
  • 是的,我试过了。不幸的是,没有任何改变。
  • 这可能是由于自动布局。如果您设置在情节提要中创建的任何对象的框架(启用自动布局),则只要需要重绘视图,它们就会恢复到由其约束定义的大小和位置。
  • @rdelmar 我已经尝试删除所有约束并将 autoresizemask 设置为 none 并将 autoresize 子视图设置为 false 以及在设置它们的框架之前。这不会消除自动布局问题吗?
  • 除非您取消选中“使用自动布局”复选框,否则自动布局处于启用状态。如果您删除所有约束,系统会为您添加它们。

标签: ios objective-c cocoa-touch swift storyboard


【解决方案1】:

这似乎是自动布局干扰子视图框架更改的问题。我找到了一种解决方法,方法是在设置子视图的框架之前将 translatesAutoresizingMaskIntoConstraints 设置为 false。这样我仍然可以允许视图的其余部分自动布局,但它不会干扰我的自定义布局更改。

subview.setTranslatesAutoresizingMaskIntoConstraints(false);
subview.frame = frame;

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    相关资源
    最近更新 更多