我尝试遍历其约束来查找宽度和高度约束,但这不太干净,并且在存在内在约束时会失败(因为我无法区分两者)。此外,这仅适用于它们实际具有宽度和高度约束的情况,如果它们依靠其他约束调整大小,则没有宽度和高度约束。
为什么对我来说这样很困难。ARG!
[view layoutIfNeeded]
。view.bounds.size.width
和view.bounds.size.height
(或者等效的frame,除非您正在操作view.transform
)来获取视图的当前宽度和高度。[view setNeedsLayout]
。[view setNeedsLayout]
和[view layoutIfNeeded]
。如果您在IB中创建了约束,则最好的解决方案是在视图控制器或视图中创建IBOutlet,以便您可以直接引用它。如果您在代码中创建了约束,则应在创建它时将其保留在内部弱属性中。如果其他人创建了约束,则需要通过检查视图上的view.constraints属性(可能是整个视图层次结构),并实现查找关键NSLayoutConstraint的逻辑来找到它。这可能是错误的做法,因为这也有效地要求您确定哪个特定的约束确定了边界大小,当没有保证有一个简单的答案时。最终的边界值可以是多个约束、多个优先级等非常复杂的系统的解,因此没有单个约束是最终值的“原因”。
layoutIfNeeded
功能强大,可以立即获取视图的frame。但是,它也会强制渲染在其上调用的视图子树中所有视图的约束条件。例如,如果您正在以编程方式添加视图,并在递归例程中对它们全部调用layoutIfNeeded
,则可能会发现您的视图层次结构渲染非常缓慢。(我是通过吃亏才学会这一点的)正如优秀答案中提到的,'setNeedsLayout`更高效,将在下一次布局传递时使frame可用,理想情况下约为1/60秒。 - shmiminitWithCoder
中吗? - MayNotBe我曾经遇到过一个类似的问题,需要给一个UITableView
添加上下边框,并且这个UITableView
根据在UIStoryboard
中设置的约束进行自适应。我可以使用- (void)viewDidLayoutSubviews
来访问已更新的约束。这对于您不需要对视图进行子类化并覆盖其布局方法非常有用。
/*** SET TOP AND BOTTOM BORDERS ON TABLE VIEW ***/
- (void)addBorders
{
CALayer *topBorder = [CALayer layer];
topBorder.frame = CGRectMake(0.0f, self.tableView.frame.origin.y, 320.0f, 0.5f);
topBorder.backgroundColor = [UIColor redColor].CGColor;
CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0.0f, (self.tableView.frame.origin.y + self.tableView.frame.size.height), 320.0f, 0.5f);
bottomBorder.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:topBorder];
[self.view.layer addSublayer:bottomBorder];
}
/*** GET AUTORESIZED FRAME DIMENSIONS ***/
- (void)viewDidLayoutSubviews{
[self addBorders];
}
如果不从viewDidLayoutSubview
方法中调用该方法,则只会正确绘制顶部边框,因为底部边框可能在屏幕外。
[super viewDidLayoutSubviews];
- Alejandro Iván-(void)layoutSubviews
{
//your code here like drawing a shadow
}
-(void)layoutSubviews
{
//your code here like drawing a shadow
}
使用 -(void)viewWillAppear:(BOOL)animated
并调用[self.view layoutIfNeeded];
- 我已经尝试过,它可以工作。
因为如果你使用-(void)viewDidLayoutSubviews
,它肯定会工作,但是每当UI需要更新/更改时,此方法都会被调用。这将变得难以管理。最好使用一个bool变量来避免这样的调用循环。记住,如果视图没有被重新分配,viewWillAppear
也会被调用。
框架仍然有效。最终,视图使用其框架属性来布局自己。它基于所有约束计算该框架。这些约束仅用于初始布局(以及在像旋转后调用layoutSubviews的视图上的任何时间)。之后,位置信息在框架属性中。您有其他观察结果吗?