wake-up-neo.com

iOS Segue - von links nach rechts -

Ich habe die anderen Beiträge auf Segues gelesen, aber keine meiner Fragen gelöst. 

Einfach gesagt, meine ViewControllers 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 ViewControllers 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.

  1. Ich verwende einen Navigationscontroller für die Funktion der Schaltfläche "Zurück" oben links. Dies verwendet den Nav-Stack und funktioniert gut.

  2. 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.

  3. Kodierung in Swift. 

  4. 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

This error is returned when I insert DCDC's code into an IBAction for my back-swipe

37
Dave G

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"

81
Michael Hudson

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.

41
rambossa

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)
            }
        )
    }
}
11
Mark Barrasso

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)
        }
    }
}
4
Annjawn

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/

4
DCDC

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. 

2
Richard Venable

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)
1
Ashwin Felix

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 ...

1

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".

0
MRizwan33

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)
    }
}
0
Felecia Genet

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.)

0
aestusLabs