Ich habe die anderen Beiträge auf Segues gelesen, aber keine meiner Fragen gelöst.
Einfach gesagt, meine ViewController
s sind wie ein Buch geordnet. Ich möchte rückwärtige Übergänge (Beispiel: von Seite 9 auf 8), um immer von links nach rechts (von oben nach rechts zu schieben). Ich möchte Vorwärtsübergänge (von Seite 9 zu 10) von rechts nach links darstellen.
Ja, die Zurück-Schaltfläche des Navigations-Controllers (oben links) wird so angezeigt, wenn Sie seitenweise blättern. Wenn Sie jedoch von einem Index aus springen, gelangen Sie mit der Zurück-Funktion des Nav-Controllers zurück zum Index.
Mein Ziel ist es, wenn ein Benutzer (z. B.) aus einem Index auf Seite 9 springt und dann nach rechts wischt, wird die Seite nach rechts verschoben und Seite 8 angezeigt. Wenn Sie sich auf Seite 8 befinden, wird die Seite nach links verschoben gehen Sie nach links und sie werden wieder auf Seite 9 sein.
Alle meine ViewController
s sind standardmäßig voreingestellt, indem sie von rechts nach links hineingleiten.
Beispiel: Stellen Sie sich das wie ein Buch vor. Wenn ich mit dem Index zu Kapitel 4 springe, dann nach rechts wischen und einen Blick aus dem Stapel werfen, komme ich wieder zum Index. Wenn Sie sich jedoch in Kapitel 4 auf Seite 394 befinden und nach rechts streichen, möchten Sie nicht zum Index zurückkehren! Sie möchten zur letzten Seite von Kapitel 3, Seite 393! Der Nav-Stack ist also keine Hilfe für mich.
Ende Beispiel
Details: 1. Ich verwende den neuen Xcode "Show" auf der Schaltfläche, um zwischen ViewControllern zu wechseln.
Ich verwende einen Navigationscontroller für die Funktion der Schaltfläche "Zurück" oben links. Dies verwendet den Nav-Stack und funktioniert gut.
Ich habe jedoch unten eine eigene benutzerdefinierte Navigationsleiste (Zurück-Schaltfläche, Start-Schaltfläche, Index-Schaltfläche, Weiter-Schaltfläche) und Gesten. Mit diesen Funktionen möchte ich eine buchähnliche Funktionalität haben.
Kodierung in Swift.
Arbeiten mit Xcode 6.3
Ich habe gelesen, dass es Animationscode gibt. Ich habe gelesen, es gibt ausführliche programmatische Übergänge, die verwendet werden können. Es scheint einfach verrückt zu sein, dass es keine einfache Möglichkeit gibt, einfach die Segmente, die ich präsentieren möchte, von links auszuwählen und die Animation leicht umzukehren.
Vielen Dank!
Versuchsprotokoll:
I tried DCDC's code:
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
Dieser Fehler wird zurückgegeben, wenn ich den DCDC-Code in eine IBAction
einfügt, um den Swipe auszuführen
So erziele ich den Effekt, ohne einen Nav-Controller zu benötigen. Versuchen Sie es stattdessen:
Schnell 4:
import UIKit
class SegueFromLeft: 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: .curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
}
)
}
}
Swift 3:
import UIKit
class SegueFromLeft: UIStoryboardSegue
{
override func perform()
{
let src = self.sourceViewController
let dst = self.destinationViewController
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransformMakeTranslation(-src.view.frame.size.width, 0)
UIView.animateWithDuration(0.25,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
dst.view.transform = CGAffineTransformMakeTranslation(0, 0)
},
completion: { finished in
src.presentViewController(dst, animated: false, completion: nil)
}
)
}
}
Klicken Sie dann im Storyboard auf den gewünschten Bereich, den Sie ändern möchten. Ändern Sie im Attribut-Inspector den Typ in "Custom" und ändern Sie die Klasse in "SegueFromLeft"
Hier ist eine Custom-Segue-Klasse, mit der Sie in Swift von links nach rechts segnen können. Es erfordert ein QuartzCore-Framework und minimale Animationen.
Schnell 2.2
import UIKit
import QuartzCore
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src: UIViewController = self.sourceViewController
let dst: UIViewController = self.destinationViewController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.25
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
src.navigationController!.view.layer.addAnimation(transition, forKey: kCATransition)
src.navigationController!.pushViewController(dst, animated: false)
}
}
Swift 3.0
import UIKit
import QuartzCore
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src: UIViewController = self.source
let dst: UIViewController = self.destination
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.25
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
src.navigationController!.view.layer.add(transition, forKey: kCATransition)
src.navigationController!.pushViewController(dst, animated: false)
}
}
Die Schaltfläche "Zurück" wird weiterhin in der Navigationsleiste des übergeordneten View-Controllers angezeigt. Sie können den Navigations-Controller für diesen View-Controller jedoch einfach deaktivieren/konfigurieren.
Akzeptierte Antwort in Swift 3 aktualisiert:
import UIKit
class SegueFromLeft: 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)
}
)
}
}
Akzeptierte Antwort aktualisiert für Swift 3 (Stand Juni 2017)
Weiterfahrt von von links nach rechts
import UIKit
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src = self.source //new enum
let dst = self.destination //new enum
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0) //Method call changed
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil) //Method call changed
}
}
}
Weiterfahrt von von rechts nach links
import UIKit
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*2, y: 0) //Double the X-Axis
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil)
}
}
}
Sie können den vordeklarierten Übergangstyp in der transitionWithView-Methode verwenden
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
Ich denke, .TransitionFlipFromLeft ist der gewünschte
Ziehen Sie zum Abschließen der Aufgabe einen neuen Ansichts-Controller in Ihr Storyboard und benennen Sie ihn mit einer ID. Dies wird das Ziel des Übergangs sein.
dann instanziieren Sie diesen View-Controller aus dem Code
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
Sie können dies entweder innerhalb der IBAction oder beispielsweise in ViewDidLoad tun, aber wahrscheinlich ist IBAction die bessere Wahl. Achten Sie darauf, die richtigen Bezeichner für Storyboard und View Controller einzugeben. Außerdem müssen Sie Ihre appDelegate-Instanz deklarieren. Hier ist die implementierte IBAction
@IBAction func Push(sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("secondVC") as! UIViewController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
UIView.transitionWithView(appDelegate.window!, duration: 0.5, options: .TransitionFlipFromLeft , animations: { () -> Void in
appDelegate.window!.rootViewController = mainVC
}, completion:nil)
}
Wenn Sie dies nicht erwartet haben, möchten Sie möglicherweise eine benutzerdefinierte Animation erstellen. Dieser Artikel ist sehr hilfreich: http://mathewsanders.com/animated-transitions-in-Swift/
Es klingt so, als würden Sie einfach versuchen, einen View-Controller vom Stack des UINavigationControllers zu entfernen, genau wie die standardmäßige Zurück-Schaltfläche.
Sie können zwei verschiedene Dinge tun. Am einfachsten ist es, Ihre benutzerdefinierte Zurück-Schaltfläche mit einer IBAction zu verbinden, die popViewControllerAnimated () aufruft:
@IBAction func tappedCustomBackButton(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
Oder Sie können ein Abroll-Segment von Ihrem zweiten View-Controller zurück zum ersten erstellen.
Segue von rechts. Sie können die Perform-Funktion in Segue wie folgt überschreiben. Fügen Sie diese Funktion in eine benutzerdefinierte Segue-Klasse ein und weisen Sie diese Klasse dem Segment .. zu. Sie funktioniert für beide Controller mit Navigationscontroller und ohne Navigationscontroller
override func perform()
{
let src = self.sourceViewController
print(src)
let dst = self.destinationViewController
print(dst)
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransformMakeTranslation(src.view.frame.size.height, 0)
UIView.animateWithDuration(0.35,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
dst.view.transform = CGAffineTransformMakeTranslation(0, 0)
},
completion: { finished in
if let navController = src.navigationController {
navController.pushViewController(dst, animated: false)
} else {
src.presentViewController(dst, animated: false, completion: nil)
} }
)
}
wenn Sie die Auswahl von links wünschen, verwenden Sie diese Option
CGAffineTransformMakeTranslation(-src.view.frame.size.height, 0)
In meinem Fall habe ich ein Sidebar-Menü erstellt ...
Ich habe einen neuen View-Controller und zwei Zollsegmente erstellt
DAS MENÜ ÖFFNEN:
import Foundation
import UIKit
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src = self.source as UIViewController
let dst = self.destination as UIViewController
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)
}
)
}
}
DAS MENÜ SCHLIESSEN:
import Foundation
import UIKit
class SegueFromRight: UIStoryboardSegue {
override func perform() {
let src = self.source as UIViewController
let dst = self.destination as UIViewController
src.view.superview?.insertSubview(dst.view, belowSubview: src.view)
src.view.transform = CGAffineTransform(translationX: 0, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
src.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
},
completion: { finished in
src.dismiss(animated: false, completion: nil)
}
)
}
}
Ich hoffe es hat dir geholfen ...
Hey Mann, ich habe die komplette Lösung einfach kopiert und an diesem Code vorbei Swift 3 geschrieben.
func menu(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MyAccountViewController") as! MyAccountViewController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.5
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
self.navigationController?.view.layer.add(transition, forKey: kCATransition)
self.navigationController?.pushViewController(vc, animated: false)
}
Hinweis: Ändern Sie den Namen Ihres ViewControllers mit dem Text "MyAccountViewController".
Verwenden Sie diese Option, um eine "Zurück-Schaltfläche" wie eine Animation zu erstellen.
class SegueRightToLeft: UIStoryboardSegue {
override func perform() {
let src = self.source //new enum
let dst = self.destination //new enum
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width/2, y: 0)
//slice the x axis translation in half
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil)
}
}
Aktualisierte die akzeptierte Antwort auf Swift 4:
class SegueFromLeft: 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)
})
}
}
Fühlen Sie sich frei, dies in die akzeptierte Antwort zu kopieren und diesen Kommentar zu löschen. (Es ist ein reines Update, nichts Neues.)