如果交互结束且动画被取消,则将视图转换强制自定义过渡回到视图控制器的原始位置是一种好习惯。我有以下实现,它决定何时以平移手势关闭视图控制器。如果平移手势较早结束,则在考虑持续时间与平移手势上的progress
值成比例之前,我希望将其动画化为原始显示的位置。
protocol AnimationControllerDelegate: AnyObject {
func shouldHandlePanelInteractionGesture() -> Bool
}
typealias PanGestureHandler = AnimationControllerDelegate & UIViewController & Animatable
final class CustomInteractionController: UIPercentDrivenInteractiveTransition, UIGestureRecognizerDelegate {
var interactionInProgress: Bool = false
private var shouldCompleteTransition: Bool = false
private var startTransitionY: CGFloat = 0
private var panGestureRecognizer: UIPanGestureRecognizer?
private weak var viewController: PanGestureHandler?
func wireToViewController(viewController: Any) {
guard let viewControllerDelegate = viewController as? PanGestureHandler else {
return
}
self.viewController = viewControllerDelegate
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestureRecognizer(_:)))
panGestureRecognizer = panGesture
panGestureRecognizer?.delegate = self
self.viewController?.view.addGestureRecognizer(panGesture)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith
otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
@objc
func handlePanGestureRecognizer(_ gestureRecognizer: UIPanGestureRecognizer) {
guard let childView = gestureRecognizer.view,
let parentView = childView.superview,
let panGestureHandler = viewController else {
return
}
switch gestureRecognizer.state {
case .began:
break
case .changed:
let translation = gestureRecognizer.translation(in: parentView)
let velocity = gestureRecognizer.velocity(in: parentView)
let state = gestureRecognizer.state
if !panGestureHandler.shouldHandlePanelInteractionGesture() && percentComplete == 0 {
return
}
let verticalMovement = translation.y / childView.bounds.height
let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
let downwardMovementPercent = fminf(downwardMovement, 1.0)
let progress = CGFloat(downwardMovementPercent)
let alphaValue = (1 - progress) * 0.4
panGestureHandler.shadowView.backgroundColor = Safety.Colors.backgroundViewColor(for: alphaValue)
if abs(velocity.x) > abs(velocity.y) && state == .began {
return
}
if !interactionInProgress {
interactionInProgress = true
startTransitionY = translation.y
viewController?.dismiss(animated: true, completion: nil)
} else {
shouldCompleteTransition = progress > 0.3
update(progress)
}
case .cancelled:
interactionInProgress = false
startTransitionY = 0
cancel()
case .ended:
interactionInProgress = false
startTransitionY = 0
if !shouldCompleteTransition {
// Can I call a custom transition here back to original position?
cancel()
} else {
finish()
}
case .failed:
interactionInProgress = false
startTransitionY = 0
cancel()
default:
break
}
}
}
如果交互结束且动画被取消,则将视图转换强制自定义过渡回到视图控制器的原始位置是一种好习惯。我有以下实现决定...
如果交互结束并且取消了动画,则将视图转换强制自定义过渡回到视图控制器的原始位置是一个好习惯。
如果交互结束并且取消了动画,则将视图转换强制自定义过渡回到视图控制器的原始位置是一个好习惯。