Ich benutze presentViewController, um einen neuen Bildschirm zu präsentieren
let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)
Dies zeigt einen neuen Bildschirm von unten nach oben, aber ich möchte, dass er von rechts nach links ohne Verwendung dargestellt wird UINavigationController
.
Ich verwende Xib anstelle von Storyboard. Wie kann ich das tun?
Antworten:
Es spielt keine Rolle, ob es ist
xib
oderstoryboard
ob Sie es verwenden. Normalerweise wird der Übergang von rechts nach links verwendet, wenn Sie einen Ansichts-Controller in den Präsentator schiebenUINavigiationController
.AKTUALISIEREN
Timing-Funktion hinzugefügt
kCAMediaTimingFunctionEaseInEaseOut
Beispielprojekt mit Swift 4- Implementierung zu GitHub hinzugefügt
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)
Scheint, als ob der
animated
Parameter in derpresentViewController
Methode in diesem Fall eines benutzerdefinierten Übergangs keine Rolle spielt. Es kann einen beliebigen Wert haben, entwedertrue
oderfalse
.quelle
Vollständiger Code für Gegenwart / Entlassung, 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) } }
quelle
Lesen Sie alle Antworten durch und sehen Sie keine richtige Lösung. Der richtige Weg, dies zu tun, besteht darin, eine benutzerdefinierte UIViewControllerAnimatedTransitioning für den präsentierten VC-Delegaten zu erstellen.
Es werden also mehr Schritte vorausgesetzt, aber das Ergebnis ist anpassbarer und weist keine Nebenwirkungen auf, z. B. das Verschieben aus der Ansicht zusammen mit der dargestellten Ansicht.
Angenommen, Sie haben einen ViewController und es gibt eine Methode zum Präsentieren
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
unddismissTransition
wird zum Animieren Ihrer View Controller verwendet. Sie übernehmen Ihren ViewController also fürUIViewControllerTransitioningDelegate
:extension ViewController: UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return presentTransition } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return dismissTransition } }
Der letzte Schritt besteht also darin, Ihren benutzerdefinierten Übergang zu erstellen:
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) }) } }
In diesem Code View Controller, der über den aktuellen Kontext dargestellt wird, können Sie Ihre Anpassungen von diesem Punkt aus vornehmen. Möglicherweise sehen Sie auch, dass Benutzerdefiniert
UIPresentationController
nützlich ist (Weitergabe mitUIViewControllerTransitioningDelegate
)quelle
Sie können auch benutzerdefinierte Segmente verwenden.
Swift 5
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: UIView.AnimationOptions.curveEaseInOut, animations: { dst.view.transform = CGAffineTransform(translationX: 0, y: 0) }, completion: { finished in src.present(dst, animated: false, completion: nil) }) } }
quelle
Versuche dies,
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)
Hier
vc
ist ViewcontrollerdashboardWorkout
in Ihrem Fall.quelle
Wenn Sie die CATransition-Methode "Quick Fix" verwenden möchten ...
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 }
und dann ...
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 }
All dies ist leider nicht wirklich richtig :(
CATransition
ist nicht wirklich für diesen Job gemacht.Beachten Sie, dass das nervige Kreuz schwarz wird, was den Effekt leider ruiniert.
Viele Entwickler (wie ich) mögen es wirklich nicht
NavigationController
. Insbesondere bei ungewöhnlichen und komplexen Apps ist es häufig flexibler, sich unterwegs nur ad-hoc zu präsentieren. Es ist jedoch nicht schwierig, einen Navigationscontroller hinzuzufügen.Gehen Sie einfach im Storyboard zum Eintrag VC und klicken Sie auf "Einbetten -> in Navi-Controller". Wirklich, das war's. Oder,
in
didFinishLaunchingWithOptions
ist es einfach Ihre nav - Controller zu bauen , wenn Sie es vorziehen ,Sie müssen die Variable wirklich nicht einmal irgendwo aufbewahren, da sie
.navigationController
immer als Eigenschaft verfügbar ist - einfach.Sobald Sie einen Navigationscontroller haben, ist es wirklich trivial, Übergänge zwischen Bildschirmen durchzuführen.
let nextScreen = instantiateViewController etc as! NextScreen navigationController? .pushViewController(nextScreen, animated: true)
und du kannst
pop
.Das gibt Ihnen jedoch nur den Standard-Apfel-Dual-Push-Effekt ...
(Der alte rutscht mit einer niedrigeren Geschwindigkeit ab, während der neue aufrutscht.)
Im Allgemeinen und überraschend müssen Sie sich normalerweise die Mühe machen, einen vollständigen benutzerdefinierten Übergang durchzuführen.
Selbst wenn Sie nur den einfachsten, häufigsten Übergang zum Verschieben / Verschieben wünschen, müssen Sie einen vollständigen benutzerdefinierten Übergang durchführen.
Glücklicherweise gibt es dazu einen Code zum Ausschneiden und Einfügen von Boilerplates in dieser Qualitätssicherung ... https://stackoverflow.com/a/48081504/294884 . Frohes neues Jahr 2018!
quelle
Importieren Sie UIKit und erstellen Sie eine Erweiterung für 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) }}
nach einfachem anruf:
let vC = YourViewController() transitionVc(vc: vC, duration: 0.5, type: .fromRight)
von links nach rechts:
let vC = YourViewController() transitionVc(vc: vC, duration: 0.5, type: .fromleft)
Sie können die Dauer mit Ihrer bevorzugten Dauer ändern ...
quelle
Versuche dies.
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)
quelle
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)
quelle
Präsentieren Sie den View Controller in iOS mit Swift von rechts nach links
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" }
Aktualisieren von: [ https://developer.apple.com/documentation/quartzcore/catransition weibl. [1 ]
quelle
Ich habe eine bessere Lösung, die für mich funktioniert hat, wenn Sie die klassische Animation von Apple beibehalten möchten, ohne den "schwarzen" Übergang zu sehen, den Sie mit CATransition () sehen. Verwenden Sie einfach die popToViewController-Methode.
Sie können nach dem ViewController suchen, den Sie benötigen
self.navigationController.viewControllers // Array of VC that contains all VC of current stack
Sie können nach dem ViewController suchen, den Sie benötigen, indem Sie nach dessen Wiederherstellungs-ID suchen.
ACHTUNG: Wenn Sie beispielsweise durch 3 Ansichts-Controller navigieren und zum letzten gelangen, möchten Sie den ersten Popup-Vorgang ausführen. In diesem Fall verlieren Sie den Verweis auf den effektiven SECOND View Controller, da der popToViewController ihn überschrieben hat. Übrigens gibt es eine Lösung: Sie können die VC, die Sie später benötigen, problemlos vor dem popToViewcontroller speichern. Es hat bei mir sehr gut funktioniert.
quelle
Das hat bei mir funktioniert:
self.navigationController?.pushViewController(controller, animated: true)
quelle