swift 3 layoutIfneeded 无法正常工作

swift 3 layoutIfneeded not working properly

要为带约束的 uiview 制作正确的动画,您必须设置新的约束值,然后调用 theView.layoutIfNeeded() ,for swift 3不起作用,而不是从视图的 whos 约束中调用 changed 。它 必须像这样从上层视图调用: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
    // ....
})

问题是,在我的情况下,我做了更改,我使用此动画的方式是针对底部视图(底部栏/横幅视图),它在向下滚动表格视图时隐藏并在一直滚动时出现到表视图的顶部。现在我已经使用 self.view.layoutIfNeeded() 更改了 swift 3 的正确代码,tableview 表现得很奇怪,速度变慢,行开始出现淡入或显示速度很慢,当向下滚动和表格视图的部分以慢动作跳跃或移动,似乎内存也从 80mb 增加到 100mb。如果我删除代码中的行,我不会得到动画,视图只是出现并随着 tableview 的滚动而消失,但是......我没有得到奇怪的行为。我还检查了视图层次结构,以检查是否以某种方式创建了奇怪的 100 个视图复制或其他内容。关于如何解决此问题的任何提示。所有这一切都在 swift 2 中使用 theView.layoutIfneeded() 正常工作,但现在调用是在上层视图中进行的.. omg..wierd acting

问题来自解决方案。

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)

试试这个以强制对 superview 进行布局更改

//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
    // ....
})

解决我的需求。感谢大家分享您的答案!

我的视图层次结构

- root view
   - uitableView
   - bottomBarView
   - bottomBannerView

由于该层次结构,我无法使用 self.view.layoutIfNeeded() 或 self.bottomBarView.superview?.layoutIfneeded(),因为它正在调用布局相同的超级视图,该超级视图也承载 tableview 并且我正在触发如果滚动超过 10 次则使用此函数,如果滚动次数少于 10 次也有此功能。所以它总是触发 layoufIfneeded 方法。我必须从一开始就按照我的想法去做。

正确的方法是创建一个承载 bottombarview 和 banner view 的容器视图,将其约束到根超级视图的底部,并将 bottomBarView 和 bottomBannerView 约束到 IT。

现在的视图层次结构是 .

-root view
  -uitableView
      -containerBottomView
           -bottomBarView
           -bottomBannerView

这样我就可以调用 self.bottomBarView.superview?.layoutIfNeeded() ,它不会在也托管 uitableview 的根视图上触发。它正确触发布局 containerBottomView。