I play with a custom and interactive view controller transistor with UIPercentDrivenInteractiveTransition . I am creating an application that represents a map (another controller). I made custom transistors with UIViewControllerAnimatedTransitioning , which animates the map display controller in the same way as the presentation style of the standard model.
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { {...} let fullScreenFrame = transitionContext.finalFrame(for: cardVC) let offsetFrame = cardVC.view.frame.offsetBy(dx: 0, dy: cardVC.view.frame.height) let finalFrame = presenting ? fullScreenFrame : offsetFrame cardVC.view.frame = presenting ? offsetFrame : fullScreenFrame containerView.addSubview(cardVC.view) UIView.animateKeyframes( withDuration: transitionDuration(using: transitionContext), delay: 0, options: UIViewKeyframeAnimationOptions.calculationModeLinear, animations: { UIView.addKeyframe( withRelativeStartTime: 0, relativeDuration: 1, animations: { [weak self] in guard let strongSelf = self else { return } backgroundView.alpha = strongSelf.presenting ? 1 : 0 }) UIView.addKeyframe( withRelativeStartTime: 0, relativeDuration: 1, animations: { cardVC.view.frame = finalFrame }) }, completion: { finished in backgroundView.removeFromSuperview() gradientView.alpha = 1 transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) }
And then I use the gesture recognizer to interactively control the firing animation:
func handleGesture(_ gestureRecognizer: UIScreenEdgePanGestureRecognizer) { let translation = gestureRecognizer.translation(in: gestureRecognizer.view) var progress = (translation.y / (UIScreen.main.bounds.height - 70)) progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0)) switch gestureRecognizer.state { case .began: interactionInProgress = true viewController.dismiss(animated: true, completion: nil) case .changed: shouldCompleteTransition = progress > 0.35 update(progress) case .cancelled: interactionInProgress = false cancel() case .ended: interactionInProgress = false if !shouldCompleteTransition { cancel() } else { finish() } default: print("Unsupported") } }
When I reject the presented view controller by dragging it, it doesn't seem to move linearly with a gesture. It seems that the Interaction Controller uses some easeInEaseOut function. Perhaps set UIPercentDrivenInteractiveTransition timingCurve to make the transition linear. Is this possible, or am I getting something wrong?
source share