UIView 动画立即完成,不考虑持续时间或延迟
UIView animation is done instantly without regards to the duration or delay
我在为我的视图的 layoutConstraints 之一设置动画时遇到了一些困难:
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.topLayoutConstraint?.constant = self.currentYPosition
self.layoutIfNeeded()
}, completion: nil)
无论我使用什么持续时间或延迟,动画都会立即完成(我的视图从以前的位置跳到新的位置)。
我检查了所有的值,它们都是正确的。
我也检查过,动画和完成被调用了。
有什么想法吗?
编辑:
@objc private func viewDragged(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: self.superview)
switch recognizer.state {
case .ended:
if (recognizer.direction == .Down) { // Collapsing the slide panel
currentYPosition = parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight
}
else if (recognizer.direction == .Up) { // Expanding the slide panel
// Substracting `minimumVisibleHeight` so that the dragable part is hidden behind the navigation bar
currentYPosition = -minimumVisibleHeight
}
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
break
case .began:
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
default:
self.layoutIfNeeded()
if (location.y < (parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight)
|| location.y > (statusBarHeight + navBarHeight)) {
currentYPosition -= HomeSlidePanelContainerView.draggingPreviousPosition - location.y
topLayoutConstraint?.constant = currentYPosition
self.layoutIfNeeded()
}
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
break
}
}
在动画块之前设置约束:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
我经常用Snapkit或者Masonry做autolayout,也许你可以试试it.It熟悉Apple的autolayout,太棒了!比如我今天用的子代码:
UIView.animate(withDuration: 1.0, animations: {
minLabel.snp.updateConstraints { (make) in
make.top.equalTo(view.snp.centerY)
}
})
self.view.layoutIfNeeded()
我已经设法找到解决方案。这可能会对其他人有所帮助,所以我正在回答我自己的问题。
我当时做的是这样的:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
如您所见,我正在更改一个值 topLayoutConstraint
,这是对 self
的约束,后者是 UIView
.
然后我尝试通过在动画闭包中调用 self.layoutIfNeeded
来为该变化设置动画。
这里的问题是 layoutIfNeeded()
适用于子视图而不是视图本身。所以在我的例子中,我试图为 self
的子视图而不是 self
本身的布局设置动画。
已将 self.layoutIfNeeded()
更改为 self.superview?.layoutIfNeeded()
瞧!
我在为我的视图的 layoutConstraints 之一设置动画时遇到了一些困难:
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.topLayoutConstraint?.constant = self.currentYPosition
self.layoutIfNeeded()
}, completion: nil)
无论我使用什么持续时间或延迟,动画都会立即完成(我的视图从以前的位置跳到新的位置)。
我检查了所有的值,它们都是正确的。 我也检查过,动画和完成被调用了。
有什么想法吗?
编辑:
@objc private func viewDragged(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: self.superview)
switch recognizer.state {
case .ended:
if (recognizer.direction == .Down) { // Collapsing the slide panel
currentYPosition = parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight
}
else if (recognizer.direction == .Up) { // Expanding the slide panel
// Substracting `minimumVisibleHeight` so that the dragable part is hidden behind the navigation bar
currentYPosition = -minimumVisibleHeight
}
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
break
case .began:
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
default:
self.layoutIfNeeded()
if (location.y < (parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight)
|| location.y > (statusBarHeight + navBarHeight)) {
currentYPosition -= HomeSlidePanelContainerView.draggingPreviousPosition - location.y
topLayoutConstraint?.constant = currentYPosition
self.layoutIfNeeded()
}
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
break
}
}
在动画块之前设置约束:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
我经常用Snapkit或者Masonry做autolayout,也许你可以试试it.It熟悉Apple的autolayout,太棒了!比如我今天用的子代码:
UIView.animate(withDuration: 1.0, animations: {
minLabel.snp.updateConstraints { (make) in
make.top.equalTo(view.snp.centerY)
}
})
self.view.layoutIfNeeded()
我已经设法找到解决方案。这可能会对其他人有所帮助,所以我正在回答我自己的问题。
我当时做的是这样的:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
如您所见,我正在更改一个值 topLayoutConstraint
,这是对 self
的约束,后者是 UIView
.
然后我尝试通过在动画闭包中调用 self.layoutIfNeeded
来为该变化设置动画。
这里的问题是 layoutIfNeeded()
适用于子视图而不是视图本身。所以在我的例子中,我试图为 self
的子视图而不是 self
本身的布局设置动画。
已将 self.layoutIfNeeded()
更改为 self.superview?.layoutIfNeeded()
瞧!