Je suis en train de jouer avec une transistion de contrôleur de vue personnalisée et interactive, avec UIPercentDrivenInteractiveTransition
. Je construis une application qui présente une carte (autre contrôleur de vue) modalement. J'ai fait des transitions personnalisées avec UIViewControllerAnimatedTransitioning
qui anime le contrôleur de vue de carte beaucoup comme le style de présentation de modèle standart.Transition interactive non linéaire
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)
})
}
Et puis-je utiliser une reconnaissance pan geste de conduire de manière interactive la rejeter 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")
}
}
Lorsque je rejette le contrôleur de vue présenté en le faisant glisser vers le bas, il ne semble pas se déplacer de façon linéaire avec le geste. Il semble que le contrôleur d'interaction utilise une fonction easeInEaseOut. Peut-être régler UIPercentDrivenInteractiveTransition
timingCurve
pour que la transition se déroule linéairement. Est-ce que c'est possible ou est-ce que je me trompe?