当自动布局约束在视图控制器生命周期中设置框架?

Posted

技术标签:

【中文标题】当自动布局约束在视图控制器生命周期中设置框架?【英文标题】:When the autolayout constraints set frames during view controller life cycle? 【发布时间】:2016-03-21 07:17:41 【问题描述】:

我使用了故事板中的自动布局约束。但是在某些情况下,我想计算子视图的动态高度。我在 viewDidAppear() 中对此进行了编码,它工作正常,因为在所有视图框架都由布局约束设置后调用此方法。这里的问题是我可以看到约束设置的帧半秒钟。然后代码重新构建视图。

我开始了解 viewDidLayout() ,它在约束设置框架后调用,以便我可以更改。但它不起作用。就像在使用约束之前调用了这个方法。

【问题讨论】:

这很复杂:bradbambara.wordpress.com/2015/01/18/object-life-cycle-uiview 令人惊讶的是,很少使用的 didMoveToWindow 通常是最好的。 (别忘了if window == nil return 【参考方案1】:

viewDidAppear 方法在视图生命周期结束时调用。因此,如果您在此处更改约束,它将始终可见。

如果您要进行的更改是一次性事件,那么您可以在方法viewWillAppear 中这样做。但这并不总是有帮助,因为此时视图绘制可能并不总是完成。所以更好的选择是将代码放在viewWillLayoutSubviewsviewDidLayoutSubviews

注意: viewWillLayoutSubviewsviewDidLayoutSubviews 将在视图的生命周期中多次调用,例如方向更改或移入和移出另一个视图或任何框架更改。 如果您要在此处放置的代码更改是一次性事件,请确保使用标志。

例如:-

- (void)viewWillLayoutSubviews     
    if(firstTime) 
        // put your constraint change code here.
    

希望这会有所帮助! :)

【讨论】:

viewWillAppear 不是“一次性事件”,如果所述视图控制器在成为和不是最顶层的视图控制器之间循环。我相信你指的方法是viewDidLoad 确实这不是“一次性事件”。您可能需要像viewWillLayoutSubviews 那样添加丑陋的检查。 viewDidLoad 与问题无关,因为此时可能不一定会加载子视图。自己试试吧。 不,你是对的。我的回答更多的是对您对加载视图控制器视图后调用的方法的评论的更正,而不是 OP 的初始问题。我很抱歉。不过你是对的,对这样的东西使用布尔值总是很恶心,但我担心这是解决 OP 所遇到问题的快速解决方案。【参考方案2】:

顾名思义,viewDidLayoutSubviews 在您的 viewController 的视图刚刚完成布局时调用,您可以假设在该动态高度,您的视图根据您的自动布局约束位于正确的位置/框架中。

Swift :

    override func viewDidLayoutSubviews() 
       // Set your constraint here
    

Objective C :

   -(void)viewDidLayoutSubviews 
   // Set your constraint here
   

【讨论】:

你能告诉我如何在objective-c中重写这个方法吗? @HirenPrajapati:如果这有帮助,请告诉我。 是的,这正是我所做的。它工作正常。但并非在所有情况下。例如,如果发生滚动内容大小更改等情况,自动布局会将视图框架设置为默认约束设置。 @HirenPrajapati :是的,因为每当您的视图控制器 viewdidlayoutsubviews 再次调用发生任何帧更改时。因此,如果您只想对 viewWillAppear 施加约束。【参考方案3】:

我不确定您在viewDidLayoutSubviews() 中实际尝试做什么。我总是通过修改覆盖此方法的布局约束值来自定义视图。

    // Called to notify the view controller that its view has just laid out its subviews
    override func viewDidLayoutSubviews() 
        //Write your code here, any constraint modification etc.
       super.viewDidLayoutSubviews()
    

【讨论】:

为什么在调用super之前?

以上是关于当自动布局约束在视图控制器生命周期中设置框架?的主要内容,如果未能解决你的问题,请参考以下文章

IOS/Autolayout:在生命周期中为代码中创建的元素设置约束

使用嵌入式视图了解自动布局生命周期和顺序

vue3 生命周期

如何让自定义视图观察包含片段的生命周期事件而不是活动?

在视图控制器生命周期中添加子视图的位置

SwiftUI |如何覆盖 viewWillAppear 等生命周期方法