Ich verwende presentViewController, um einen neuen Bildschirm zu präsentieren
let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)
Dies stellt einen neuen Bildschirm von unten nach oben dar, aber ich möchte, dass er von rechts nach links angezeigt wird, ohne UINavigationController
zu verwenden.
Ich verwende Xib anstelle des Storyboards. Wie kann ich das tun?
Es spielt keine Rolle, ob Sie xib
oder storyboard
verwenden. Normalerweise wird der Übergang von rechts nach links verwendet, wenn Sie einen View-Controller in die UINavigiationController
des Presenters verschieben.
UPDATE
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)
Anscheinend ist der Parameter animated
in der Methode presentViewController
in diesem Fall eines benutzerdefinierten Übergangs nicht wirklich wichtig. Es kann einen beliebigen Wert haben, entweder true
oder false
.
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)
}
}
Sie können auch benutzerdefinierte Segmente verwenden.
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)
}
)
}
}
Lesen Sie alle Antworten und können keine korrekte Lösung sehen. Der richtige Weg ist, benutzerdefinierte UIViewControllerAnimatedTransitioning für präsentierte VC -Delegate vorzunehmen.
Es wird also davon ausgegangen, dass Sie mehr Schritte ausführen, das Ergebnis ist jedoch anpassbarer und hat keine Nebeneffekte, z.
Nehmen Sie an, Sie haben 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
und dismissTransition
werden zur Animation Ihrer View-Controller verwendet. Sie übernehmen also Ihren ViewController in UIViewControllerTransitioningDelegate
:
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 ist also die Erstellung eines benutzerdefinierten Übergangs:
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 dieser Codeansicht wird der Controller über den aktuellen Kontext dargestellt. Hier können Sie Anpassungen vornehmen. Sie können auch sehen, dass benutzerdefinierte UIPresentationController
nützlich ist (übergeben Sie mit UIViewControllerTransitioningDelegate
).
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 ist vc
viewcontroller, in Ihrem Fall dashboardWorkout
.
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
}
CATransition
ist für diese Arbeit nicht wirklich geeignet.
Beachten Sie, dass Sie das ärgerliche cross-Fade zu schwarz bekommen, was den Effekt leider ruiniert.
Viele Entwickler (wie ich) mögen NavigationController
wirklich nicht. Oft ist es flexibler, Ad-hoc-Präsentationen zu erstellen, insbesondere für ungewöhnliche und komplexe Apps. Es ist jedoch nicht schwierig, einen Nav-Controller "hinzuzufügen".
gehen Sie einfach im Storyboard zum Eintrag VC und klicken Sie auf "embed -> in nav controller". Wirklich das ist es. Oder,
in didFinishLaunchingWithOptions
ist es einfach, Ihren Nav-Controller zu bauen, wenn Sie möchten
sie brauchen die Variable wirklich nicht überall zu behalten, da .navigationController
immer als Eigenschaft verfügbar ist - einfach.
Wenn Sie einmal einen navigationController haben, ist es einfach, Übergänge zwischen Bildschirmen durchzuführen.
let nextScreen = instantiateViewController etc as! NextScreen
navigationController?
.pushViewController(nextScreen, animated: true)
und Sie können pop
.
(Die alte rutscht mit niedrigerer Geschwindigkeit ab, während die neue weiter gleitet.)
Im Allgemeinen und überraschenderweise müssen Sie sich normalerweise anstrengen, um einen vollständigen benutzerdefinierten Übergang durchzuführen.
Selbst wenn Sie nur den einfachsten, häufigsten Übergangs- oder Ausstiegsübergang wünschen, müssen Sie einen vollständigen benutzerdefinierten Übergang durchführen.
Zum Glück gibt es auf dieser QA einige Code-Codes für das Kopieren und Einfügen ... https://stackoverflow.com/a/48081504/294884 .
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)
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"
}
Refrence By: [ https://developer.Apple.com/documentation/quartzcore/catransition ?[1]
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 einem einfachen 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 ...
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)