调用 layoutIfNeeded 后视图未立即显示
Posted
技术标签:
【中文标题】调用 layoutIfNeeded 后视图未立即显示【英文标题】:View not displayed immediately after layoutIfNeeded is called 【发布时间】:2017-03-19 21:26:53 【问题描述】:我正在尝试使用自动布局制作一个简单的从顶部向下滑动的动画(在 SnapKit
的帮助下)。
下面是我用来生成视图、设置其约束并强制重新加载(从而显示)所述视图的代码。在同一代码中,我将顶部约束更改为不同的值并在动画块中调用layoutIfNeeded
。
然而,发生的事情是视图显示在预期位置,没有任何动画。
这是在短暂延迟后(用于其他目的)在方法中调用的代码:
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute:
self.view.addSubview(view)
view.backgroundColor = .black
view.snp.makeConstraints (make) -> Void in
make.left.right.equalToSuperview()
make.height.equalTo(200)
make.bottom.equalTo(self.view.snp.top) // Pin view to top to prepare slide-down animation
view.setNeedsLayout()
view.layoutIfNeeded()
view.snp.updateConstraints (make) -> Void in
make.bottom.equalTo(self.view.snp.top).offset(200)
view.setNeedsLayout()
UIView.animate(withDuration: 5, animations:
view.layoutIfNeeded()
)
)
【问题讨论】:
我看到了几个潜在的原因。 (1) 看起来您正试图在单独的线程中进行 UI 更新。我很惊讶它甚至可以工作。如果您以这种方式编码,那将是一个主要的禁忌。 (2) 为什么在 UIView.animate 中调用 setNeedsLayout() 和 layoutIfNeeded() outside?这可能是罪魁祸首。 (3) 约束变化。也许这与 SnapKit 相关,但调用 updateContraints() 不是我在尝试更改约束然后为约束设置动画时所做的事情。我更改其中的常量/乘数。 (1) 之后就没想过。谢谢。任何提示我应该如何在一定延迟后调用方法来进行 UI 更新?Sleep()
显然也是一种不好的方式,因为它会阻塞。 (2) 我需要先设置视图,然后才能对其进行动画处理。 (3) SnapKit 的UpdateConstraint 就是这样做的。如果你有一个给定的约束,我会比较你是否只更新常量/乘数。
@dfd DispatchQueue.main
确实在使用main thread
,所以不用担心(来源:hackingwithswift.com/read/9/4/…)。
这个问题的标题具有误导性。似乎更多的是关于约束和动画。 layoutIfNeeded() 与视图是否在屏幕上的关系为零。如果渲染系统不忙于长时间运行的进程,它将把它放在屏幕上,但它再次保证不被渲染。
【参考方案1】:
感谢In Swift, how do I animate a UIView with auto-layout like a page sliding in?我找到了罪魁祸首。
虽然我不是 100% 明白为什么会这样,但 layoutIfNeeded
需要从超级视图调用,而不是视图本身。
所以调用self.view.layoutIfNeeded()
是正确的方法。请注意,view
是当前正在添加的 UIView
,而 self.view
是超级视图,其中正在添加 view
。
【讨论】:
在同一段代码中同时使用self.view
和view
,而这些名称指的是两个不同的对象,这听起来很令人困惑。回答后一切都开始工作了吗?如果是这样,您可以接受您的答案,以便获得积分。 :)
是的,命名不是很聪明 :-) 它确实解决了这个问题。不过只能在 2 天内接受我自己的答案。
啊,好的。很高兴你知道了!以上是关于调用 layoutIfNeeded 后视图未立即显示的主要内容,如果未能解决你的问题,请参考以下文章
为啥在子视图中添加图层蒙版时需要调用 layoutIfNeeded()?
如果 layoutIfNeeded() 被调用,UIView 约束不会动画
在 UITableView 上为 layoutIfNeeded 设置动画而不为 UITableViewCells 设置动画