swift 3 layoutIfneeded 无法正常工作
Posted
技术标签:
【中文标题】swift 3 layoutIfneeded 无法正常工作【英文标题】:swift 3 layoutIfneeded not working properly 【发布时间】:2016-10-19 12:55:31 【问题描述】:要使带有约束的 uiview 正确动画,您必须设置新的约束值,然后调用 theView.layoutIfNeeded() ,for swift 3 这不起作用,而不是从视图的 whos 约束中调用被改变了。它必须像这样从上视图调用:self.view.layoutIfNeeded()。 例如:
UIView.animate(withDuration: 0.1,
delay: 0.1,
options: UIViewAnimationOptions.curveEaseIn,
animations: () -> Void in
constraintHeight.constant = 10.00
// instead of myView.layoutIfNeeded() // Swift 2
self.view.layoutIfNeeded() // Swift 3
, completion: (finished) -> Void in
// ....
)
问题是,在我的情况下,我进行了更改,我使用此动画的方式是用于底部视图(底部栏/横幅视图),它在向下滚动 tableview 时隐藏并在一直到在 tableview 顶部。现在我已经使用 self.view.layoutIfNeeded() 更改了 swift 3 的正确代码,当向下和向上滚动 tableview 的部分时,tableview 行为怪异、变慢、行开始淡入或呈现速度很慢以慢动作跳跃或移动,似乎内存也从 80mb 增加到 100mb 。如果我消除代码中的行,我没有得到动画,视图只是出现并随着 tableview 的滚动而消失,但是......我没有得到奇怪的行为。我还检查了视图层次结构以检查是否没有创建奇怪的 100 个视图复制或其他东西.. 关于如何解决这个问题的任何提示。所有这一切都在 swift 2 中使用 View.layoutIfneeded() 运行良好,但现在调用是在上视图中进行的.. omg..wierd 作用
问题来自Swift 3 UIView animation 解决方案。
【问题讨论】:
【参考方案1】:试试这个来强制改变超级视图的布局
//Force to complete all changes.
self.view.superview.layoutIfNeeded()
//Update constant
constraintHeight.constant = 10.00
UIView.animate(withDuration: 0.1,
delay: 0.1,
options: UIViewAnimationOptions.curveEaseIn,
animations: () -> Void in
self.view.superview.layoutIfNeeded()
, completion: (finished) -> Void in
// ....
)
【讨论】:
这将是正确的语义方式,说我需要通过调用超级视图上的方法来布局 thisView。 :D。在我的情况下,我的 uitableview 仍然混乱,因为所有视图都在同一级别上,超级视图视图是根视图,它也托管 uitableview。最后不得不做一个containerBottomView【参考方案2】:解决我的需求。谢谢大家分享你的答案!
我的视图层次结构
- root view
- uitableView
- bottomBarView
- bottomBannerView
由于该层次结构,它不能使用 self.view.layoutIfNeeded() 或 self.bottomBarView.superview?.layoutIfneeded(),因为它正在调用布局相同的超级视图,该超级视图也托管 tableview 并且我触发了这个函数如果滚动超过 10 并且如果它更少.. 所以它总是触发 layoutIfneeded 方法。我必须按照我从一开始的想法去做。
正确的做法是做一个容器视图托管bottombarview和banner view,让它约束到root super view的底部,把bottomBarView和bottomBannerView约束到IT。
视图层次现在是 .
-root view
-uitableView
-containerBottomView
-bottomBarView
-bottomBannerView
这样我可以调用 self.bottomBarView.superview?.layoutIfNeeded() ,它不会在也托管 uitableview 的根视图上触发。它正确触发布局 containerBottomView。
【讨论】:
【参考方案3】:UIView.animate(withDuration: 0.5, delay: 0.3, options: [.repeat, .curveEaseOut, .autoreverse], animations:
// perform your animation here .
self.username.center.x += self.view.bounds.width
self.view.layoutIfNeeded()
, completion: nil)
【讨论】:
正确的方法是 self.whateverView.superview?.layoutIfNeeded() ,但考虑到视图层次结构,为了我的需要,我必须创建一个容器视图。所以它不会在也托管 uitableview 的根视图上触发,最糟糕的是,因为我称之为计数滚动,它实际上总是被调用。因此。它总是试图从根视图向下布局所有内容。检查我的最终答案:d,以防你有一天遇到同样的问题。谢谢分享以上是关于swift 3 layoutIfneeded 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
调用 layoutIfNeeded 后 Snapkit 3.0 无法获得正确的帧
swift 不确定 layoutIfNeeded setNeedsUpdateConstraints 或 updateConstraints setNeedsLayout