今天研究约束时,作在页面上动态添加View时页面不能很好的更新约束,找到了这篇文章,解决了我的大问题,在此感谢博主。
用到自动约束,就离不开一下四个方法:
@interface UIView (UIConstraintBasedLayoutCoreMethods)
- (void)updateConstraintsIfNeeded NS_AVAILABLE_IOS(6_0); // Updates the constraints from the bottom up for the view hierarchy rooted at the receiver. UIWindow's implementation creates a layout engine if necessary first.
- (void)updateConstraints NS_AVAILABLE_IOS(6_0); // Override this to adjust your special constraints during a constraints update pass
- (BOOL)needsUpdateConstraints NS_AVAILABLE_IOS(6_0);
- (void)setNeedsUpdateConstraints NS_AVAILABLE_IOS(6_0);
@end
而这四个方法,对于它们的具体的用途和调用时机理解,很长一段时间我是迷迷糊糊的。经过一番研究,现在就试着把它解释清楚!!!
- (void)updateConstraintsIfNeeded
官网文档的解释:
Updates the constraints for the receiving view and its subviews.
Whenever a new layout pass is triggered for a view, the system invokes this method to ensure that any constraints for the view and its subviews are updated with information from the current view hierarchy and its constraints. This method is called automatically by the system, but may be invoked manually if you need to examine the most up to date constraints.
Subclasses should not override this method.
更新视图和它的子视图的约束。
每当一个新的布局,通过触发一个视图,系统调用此方法以确保视图和其子视图的任何约束与当前视图层次结构和约束信息更新。这种方法被系统自动调用,但如果需要检查最新的约束条件,可以手动调用这个方法。
子类不应重写此方法。
注解:立即出发约束更新。
- (void)updateConstraints
官网文档的解释:
Updates constraints for the view.
Custom views that set up constraints themselves should do so by overriding this method. When your custom view notes that a change has been made to the view that invalidates one of its constraints, it should immediately remove that constraint, and then call setNeedsUpdateConstraints to note that constraints need to be updated. Before layout is performed, your implementation of updateConstraints will be invoked, allowing you to verify that all necessary constraints for your content are in place at a time when your custom view’s properties are not changing.
You must not invalidate any constraints as part of your constraint update phase. You also must not invoke a layout or drawing phase as part of constraint updating.
Important:Important
Call [super updateConstraints] as the final step in your implementation.
更新视图的约束。
自定义视图应该通过重写此方法来设置自己的约束。当你的自定义视图有某个约束发生了变化或失效了,应该立即删除这个约束,然后调用setNeedsUpdateConstraints标记约束需要更新。系统在进行布局layout之前,会调用updateConstraints,让你确认(设置)在视图的属性不变时的必要约束。在更新约束阶段你不应该使任何一个约束失效,而且不能让layerout和drawing作为更新约束的一部分。
重要提示:要在实现的最后调用[super updateConstraints]。
注解:自定义view应该重写此方法在其中建立constraints.
- (BOOL)needsUpdateConstraints
这个很简单,返回是否需要更新约束。constraint-based layout system使用此返回值去决定是否需要调用updateConstraints作为正常布局过程的一部分。
- (void)setNeedsUpdateConstraints
官方文档解释:
Controls whether the view’s constraints need updating.
When a property of your custom view changes in a way that would impact constraints, you can call this method to indicate that the constraints need to be updated at some point in the future. The system will then call updateConstraints as part of its normal layout pass. Updating constraints all at once just before they are needed ensures that you don’t needlessly recalculate constraints when multiple changes are made to your view in between layout passes.
控制视图的约束是否需要更新。
当你的自定义视图的属性改变切影响到约束,你可以调用这个方法来标记未来的某一点上需要更新的约束。然后系统将调用updateconstraints。
注解:这个方法和updateConstraintsIfNeeded关系有点暧昧,updateConstraintsIfNeeded是立即更新,二这个方法是标记需要更新,然后系统决定更新时机。
这里再补充一下Auto layout知识
Auto layout在view显示之前,还有两个步骤:updating constraints 和laying out views。每一个步骤都依赖于上一个。display依赖layout,而layout依赖updating constraints。 updating constraints->layout->display
第一步:
updating constraints,被称为测量阶段,其从下向上(from subview to super view),为下一步layout准备信息。可以通过调用方法setNeedUpdateConstraints去触发此步。constraints的改变也会自动的触发此步。但是,当你自定义view的时候,如果一些改变可能会影响到布局的时候,通常需要自己去通知Auto layout,updateConstraintsIfNeeded。
自定义view的话,通常可以重写updateConstraints方法,在其中可以添加view需要的局部的contraints。
第二步:
layout,其从上向下(from super view to subview),此步主要应用上一步的信息去设置view的center和bounds。可以通过调用setNeedsLayout去触发此步骤,此方法不会立即应用layout。如果想要系统立即的更新layout,可以调用layoutIfNeeded。另外,自定义view可以重写方法layoutSubViews来在layout的工程中得到更多的定制化效果。
第三步:
display,此步时把view渲染到屏幕上,它与你是否使用Auto layout无关,其操作是从上向下(from super view to subview),通过调用setNeedsDisplay触发,
因为每一步都依赖前一步,因此一个display可能会触发layout,当有任何layout没有被处理的时候,同理,layout可能会触发updating constraints,当constraint system更新改变的时候。
需要注意的是,这三步不是单向的,constraint-based layout是一个迭代的过程,layout过程中,可能去改变constraints,有一次触发updating constraints,进行一轮layout过程。
注意:如果你每一次调用自定义layoutSubviews都会导致另一个布局传递,那么你将会陷入一个无限循环中。
本文转载自http://blog.csdn.net/gang544043963/article/details/52440621
感谢博主的分享。