J'utilise presentViewController pour présenter un nouvel écran
let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)
Cela présente un nouvel écran de bas en haut mais je veux qu’il soit présenté de droite à gauche sans utiliser UINavigationController
.
J'utilise Xib au lieu du storyboard, alors comment puis-je faire cela?
Peu importe que vous utilisiez xib
ou storyboard
. Normalement, la transition de droite à gauche est utilisée lorsque vous poussez un contrôleur de vue dans la variable UINavigiationController
du présentateur.
METTRE À JOUR
Ajout de la fonction de minutage kCAMediaTimingFunctionEaseInEaseOut
Exemple de projet avec implémentation de Swift 4 ajoutée à GitHub
Swift 3 & 4.2
let transition = CATransition()
transition.duration = 0.5
transition.type = CATransitionType.Push
transition.subtype = CATransitionSubtype.fromRight
transition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
present(dashboardWorkout, animated: false, completion: nil)
ObjC
CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.5;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:dashboardWorkout animated:false completion:nil];
Swift 2.x
let transition = CATransition()
transition.duration = 0.5
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
view.window!.layer.addAnimation(transition, forKey: kCATransition)
presentViewController(dashboardWorkout, animated: false, completion: nil)
On dirait que le paramètre animated
dans la méthode presentViewController
n'a pas vraiment d'importance dans ce cas de transition personnalisée. Il peut avoir n'importe quelle valeur, soit true
ou false
.
Code complet pour présenter/congédier, Swift 3
extension UIViewController {
func presentDetail(_ viewControllerToPresent: UIViewController) {
let transition = CATransition()
transition.duration = 0.25
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
self.view.window!.layer.add(transition, forKey: kCATransition)
present(viewControllerToPresent, animated: false)
}
func dismissDetail() {
let transition = CATransition()
transition.duration = 0.25
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
self.view.window!.layer.add(transition, forKey: kCATransition)
dismiss(animated: false)
}
}
Vous pouvez également utiliser Segue personnalisé.
Swift 3
class SegueFromRight: UIStoryboardSegue
{
override func perform()
{
let src = self.source
let dst = self.destination
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
}
)
}
}
Lisez toutes les réponses et ne voyez pas la solution correcte. La bonne façon de le faire est de créer un délégué UIViewControllerAnimatedTransitioning personnalisé pour le délégué VC présenté.
Donc, cela suppose de faire plus d’étapes, mais le résultat est plus personnalisable et n’a pas certains effets secondaires, comme le fait de quitter une vue avec la vue présentée.
Alors, supposons que vous avez ViewController, et il existe une méthode pour présenter
var presentTransition: UIViewControllerAnimatedTransitioning?
var dismissTransition: UIViewControllerAnimatedTransitioning?
func showSettings(animated: Bool) {
let vc = ... create new vc to present
presentTransition = RightToLeftTransition()
dismissTransition = LeftToRightTransition()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = self
present(vc, animated: true, completion: { [weak self] in
self?.presentTransition = nil
})
}
presentTransition
et dismissTransition
sont utilisés pour animer vos contrôleurs de vue. Vous adoptez donc votre ViewController à UIViewControllerTransitioningDelegate
:
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return presentTransition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return dismissTransition
}
}
La dernière étape consiste donc à créer votre transition personnalisée:
class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning {
let duration: TimeInterval = 0.25
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
container.addSubview(toView)
toView.frame.Origin = CGPoint(x: toView.frame.width, y: 0)
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
toView.frame.Origin = CGPoint(x: 0, y: 0)
}, completion: { _ in
transitionContext.completeTransition(true)
})
}
}
class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning {
let duration: TimeInterval = 0.25
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
let fromView = transitionContext.view(forKey: .from)!
container.addSubview(fromView)
fromView.frame.Origin = .zero
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: {
fromView.frame.Origin = CGPoint(x: fromView.frame.width, y: 0)
}, completion: { _ in
fromView.removeFromSuperview()
transitionContext.completeTransition(true)
})
}
}
Dans la mesure où ce contrôleur de vue de code est présenté sur le contexte actuel, vous pouvez effectuer vos personnalisations à partir de ce point. Aussi, vous pouvez constater que la personnalisation UIPresentationController
est également utile (transmettez-la à l'aide de UIViewControllerTransitioningDelegate
)
Essaye ça,
let animation = CATransition()
animation.duration = 0.5
animation.type = kCATransitionPush
animation.subtype = kCATransitionFromRight
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
vc.view.layer.addAnimation(animation, forKey: "SwitchToView")
self.presentViewController(vc, animated: false, completion: nil)
Ici vc
est viewcontroller, dashboardWorkout
dans votre cas.
class AA: UIViewController
func goToBB {
let bb = .. instantiateViewcontroller, storyboard etc .. as! AlreadyOnboardLogin
let tr = CATransition()
tr.duration = 0.25
tr.type = kCATransitionMoveIn // use "MoveIn" here
tr.subtype = kCATransitionFromRight
view.window!.layer.add(tr, forKey: kCATransition)
present(bb, animated: false)
bb.delegate, etc = set any other needed values
}
et alors ...
func dismissingBB() {
let tr = CATransition()
tr.duration = 0.25
tr.type = kCATransitionReveal // use "Reveal" here
tr.subtype = kCATransitionFromLeft
view.window!.layer.add(tr, forKey: kCATransition)
dismiss(self) .. or dismiss(bb), or whatever
}
CATransition
n'est pas vraiment fait pour faire ce travail.
Notez que vous obtiendrez le fade cross fade to black qui gâche malheureusement l'effet.
De nombreux développeurs (comme moi) n'aiment vraiment pas utiliser NavigationController
. Souvent, il est plus flexible de présenter de manière ad hoc au fur et à mesure, en particulier pour les applications inhabituelles et complexes. Cependant, il n’est pas difficile d’ajouter un contrôleur de navigation.
simplement sur le storyboard, allez à l’entrée VC et cliquez sur "intégrer -> dans le contrôleur de navigation". Vraiment c'est ça. Ou,
dans didFinishLaunchingWithOptions
il est facile de construire votre contrôleur de navigation si vous préférez
vous n'avez même pas besoin de conserver la variable où que vous soyez, car .navigationController
est toujours disponible en tant que propriété - c'est facile.
Vraiment, une fois que vous avez un navigateurContrôleur, il est facile de faire des transitions entre les écrans,
let nextScreen = instantiateViewController etc as! NextScreen
navigationController?
.pushViewController(nextScreen, animated: true)
et vous pouvez pop
.
(L'ancien glisse moins vite que le nouveau glisse.)
De manière générale et surprenante, vous devez généralement vous efforcer de réaliser une transition personnalisée complète.
Même si vous voulez juste la transition la plus simple, la plus courante, le transfert/le déplacement, vous devez effectuer une transition personnalisée complète.
Heureusement, pour ce faire, il y a du copier/coller du code standard sur ce QA ... https://stackoverflow.com/a/48081504/294884 . Bonne année 2018!
Essaye ça.
let transition: CATransition = CATransition()
transition.duration = 0.3
transition.type = kCATransitionReveal
transition.subtype = kCATransitionFromLeft
self.view.window!.layer.addAnimation(transition, forKey: nil)
self.dismissViewControllerAnimated(false, completion: nil)
présent contrôleur de vue de droite à gauche dans iOS avec Swift
func FrkTransition()
{
let transition = CATransition()
transition.duration = 2
transition.type = kCATransitionPush
transitioningLayer.add(transition,forKey: "transition")
// Transition to "blue" state
transitioningLayer.backgroundColor = UIColor.blue.cgColor
transitioningLayer.string = "Blue"
}
Refrence By: [ https://developer.Apple.com/documentation/quartzcore/catransition][1]
importer UIKit et créer une extension pour UIViewController:
extension UIViewController {
func transitionVc(vc: UIViewController, duration: CFTimeInterval, type: CATransitionSubtype) {
let customVcTransition = vc
let transition = CATransition()
transition.duration = duration
transition.type = CATransitionType.Push
transition.subtype = type
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
present(customVcTransition, animated: false, completion: nil)
}}
après appel simlpy:
let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromRight)
de gauche à droite:
let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromleft)
vous pouvez changer la durée avec votre durée préférée ...
let transition = CATransition()
transition.duration = 0.25
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
tabBarController?.view.layer.add(transition, forKey: kCATransition)
self.navigationController?.popToRootViewController(animated: true)