【发布时间】: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() 与视图是否在屏幕上的关系为零。如果渲染系统不忙于长时间运行的进程,它将把它放在屏幕上,但它再次保证不被渲染。
标签: ios swift autolayout snapkit