UIViewPropertyAnimator AutoLayout 完成问题
UIViewPropertyAnimator AutoLayout Completion Issue
我正在使用 UIViewPropertyAnimator 来 运行 数组交互式动画,我遇到的一个问题是每当我反转动画时我都无法 运行 动画再次向前.
我正在使用三个函数与平移手势识别器一起处理动画。
private var runningAnimations = [UIViewPropertyAnimator]()
private func startInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
if runningAnimations.isEmpty {
animateTransitionIfNeeded(gestureRecognizer: gestureRecognizer, state: state, duration: duration)
}
for animator in runningAnimations {
animator.pauseAnimation()
animationProgressWhenInterrupted = animator.fractionComplete
}
}
private func animateTransitionIfNeeded(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
guard runningAnimations.isEmpty else {
return
}
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
switch state {
case .expanded:
// change frame
case .collapsed:
// change frame
}
}
frameAnimator.isReversed = false
frameAnimator.addCompletion { _ in
print("remove all animations")
self.runningAnimations.removeAll()
}
self.runningAnimations.append(frameAnimator)
for animator in runningAnimations {
animator.startAnimation()
}
}
private func updateInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, fractionComplete: CGFloat) {
if runningAnimations.isEmpty {
print("empty")
}
for animator in runningAnimations {
animator.fractionComplete = fractionComplete + animationProgressWhenInterrupted
}
}
我注意到在我反转动画然后调用 animateTransitionIfNeeded 之后,frameAnimator 被附加到 运行ning 动画但是当我在之后立即调用 updateInteractiveTransition 并检查 运行ningAnimations 时,它是空的.
所以我相信这可能与 swift 如何处理内存或 UIViewAnimating 如何完成动画有关。
有什么建议吗?
我开始意识到我遇到的问题是 UIViewPropertyAnimator 如何在反转时处理布局约束。
我无法在网上或官方文档中找到更多详细信息,但我确实发现这很有帮助。
Animator just animates views into new frames. However, reversed or not, the new constraints still hold regardless of whether you reversed the animator or not. Therefore after the animator finishes, if later autolayout again lays out views, I would expect the views to go into places set by currently active constraints. Simply said: The animator animates frame changes, but not constraints themselves. That means reversing animator reverses frames, but it does not reverse constraints - as soon as autolayout does another layout cycle, they will be again applied.
像往常一样设置约束并调用 view.layoutIfNeeded()
animator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
[unowned self] in
switch state {
case .expanded:
self.constraintA.isActive = false
self.constraintB.isActive = true
self.view.layoutIfNeeded()
case .collapsed:
self.constraintB.isActive = false
self.constraintA.isActive = true
self.view.layoutIfNeeded()
}
}
现在,由于我们的动画师能够反转,我们添加了一个完成处理程序,以确保在使用结束位置完成时激活正确的约束。
animator.addCompletion { [weak self] (position) in
if position == .start {
switch state {
case .collapsed:
self?.constraintA.isActive = false
self?.constraintB.isActive = true
self?.view.layoutIfNeeded()
case .expanded:
self?.constraintA.isActive = false
self?.constraintB.isActive = true
self?.view.layoutIfNeeded()
}
}
}
The animator operates on animatable properties of views, such as the frame, center, alpha, and transform properties, creating the needed animations from the blocks you provide.
这是文档的关键部分。
您可以适当地设置动画:
frame、center、alpha 和 transform,因此您将无法正确设置 NSConstraints 的动画。
您应该在 addAnimations
块
内修改视图框架
我正在使用 UIViewPropertyAnimator 来 运行 数组交互式动画,我遇到的一个问题是每当我反转动画时我都无法 运行 动画再次向前.
我正在使用三个函数与平移手势识别器一起处理动画。
private var runningAnimations = [UIViewPropertyAnimator]()
private func startInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
if runningAnimations.isEmpty {
animateTransitionIfNeeded(gestureRecognizer: gestureRecognizer, state: state, duration: duration)
}
for animator in runningAnimations {
animator.pauseAnimation()
animationProgressWhenInterrupted = animator.fractionComplete
}
}
private func animateTransitionIfNeeded(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
guard runningAnimations.isEmpty else {
return
}
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
switch state {
case .expanded:
// change frame
case .collapsed:
// change frame
}
}
frameAnimator.isReversed = false
frameAnimator.addCompletion { _ in
print("remove all animations")
self.runningAnimations.removeAll()
}
self.runningAnimations.append(frameAnimator)
for animator in runningAnimations {
animator.startAnimation()
}
}
private func updateInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, fractionComplete: CGFloat) {
if runningAnimations.isEmpty {
print("empty")
}
for animator in runningAnimations {
animator.fractionComplete = fractionComplete + animationProgressWhenInterrupted
}
}
我注意到在我反转动画然后调用 animateTransitionIfNeeded 之后,frameAnimator 被附加到 运行ning 动画但是当我在之后立即调用 updateInteractiveTransition 并检查 运行ningAnimations 时,它是空的.
所以我相信这可能与 swift 如何处理内存或 UIViewAnimating 如何完成动画有关。
有什么建议吗?
我开始意识到我遇到的问题是 UIViewPropertyAnimator 如何在反转时处理布局约束。 我无法在网上或官方文档中找到更多详细信息,但我确实发现这很有帮助。
Animator just animates views into new frames. However, reversed or not, the new constraints still hold regardless of whether you reversed the animator or not. Therefore after the animator finishes, if later autolayout again lays out views, I would expect the views to go into places set by currently active constraints. Simply said: The animator animates frame changes, but not constraints themselves. That means reversing animator reverses frames, but it does not reverse constraints - as soon as autolayout does another layout cycle, they will be again applied.
像往常一样设置约束并调用 view.layoutIfNeeded()
animator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
[unowned self] in
switch state {
case .expanded:
self.constraintA.isActive = false
self.constraintB.isActive = true
self.view.layoutIfNeeded()
case .collapsed:
self.constraintB.isActive = false
self.constraintA.isActive = true
self.view.layoutIfNeeded()
}
}
现在,由于我们的动画师能够反转,我们添加了一个完成处理程序,以确保在使用结束位置完成时激活正确的约束。
animator.addCompletion { [weak self] (position) in
if position == .start {
switch state {
case .collapsed:
self?.constraintA.isActive = false
self?.constraintB.isActive = true
self?.view.layoutIfNeeded()
case .expanded:
self?.constraintA.isActive = false
self?.constraintB.isActive = true
self?.view.layoutIfNeeded()
}
}
}
The animator operates on animatable properties of views, such as the frame, center, alpha, and transform properties, creating the needed animations from the blocks you provide.
这是文档的关键部分。 您可以适当地设置动画: frame、center、alpha 和 transform,因此您将无法正确设置 NSConstraints 的动画。
您应该在 addAnimations
块