AnimatedTransitioning - fromView wird nach der Animation nicht mehr angezeigt

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • AnimatedTransitioning - fromView wird nach der Animation nicht mehr angezeigt

    Hallo,

    ich habe eine Animation mit AnimatedTransitioning gemacht, diese funktioniert auch wie geplant, nur verschwindet die fromView, nachdem die Animation abgeschlossen ist, von der ContentView. Habe dann im Internet gelesen, dass das ein Bug sein soll und das ganze wie folgt gehardcoded:

    Quellcode

    1. if let window = UIApplication.sharedApplication().keyWindow {
    2. if let viewController = window.rootViewController {
    3. window.addSubview(viewController.view)
    4. }
    5. }

    Die View wird mir jetzt zwar weiterhin angezeigt, doch zum einen ändert diese View nach der Animation noch leicht ihre Position, was natürlich überhaupt nicht passt.

    Nachdem ViewTransition stattfindet, animiere ich auch Buttons der fromView.


    Quellcode

    1. presentViewController(menuViewController, animated: true, completion: nil)
    2. UIView.animateWithDuration(1.5, animations: {
    3. // some work
    4. }, completion: { _ in
    5. //some work
    6. })
    Nachdem das Transitioning der Views aber fertig ist, springen die Buttons zurück an ihre Ursprungspositionen, was natürlich nicht gewünscht ist. (keine Ahnung ob das mit dem hardgecodeden Code zu tun hat)

    Gibt es da irgendeine andere Möglichkeit, das zu lösen?
    Da ich noch User Interaction brauche (1 Button um die Animation wieder rückgängig zu machen), fällt auch die Möglichkeit der Snapshots weg.

    Ein Lösungsweg der mir noch eingefallen wäre, weiß aber nicht ob das funktioniert:

    Ich snapshote die fromView und adde einen neuen Button auf die Content View.
    Aber: Wie funktioniert das dann mit der ButtonAction?

    Danke im Voraus schon für alle Antworten!

    LG
  • Was soll bitte das erste Listing bewirken? Du fügst einem Fenster einen View hinzu, der sowieso schon in dem Fenster liegt. Das ist Unsinn.

    Wenn du den Wechsel zwischen Viewcontrollern selbst animieren willst, solltest du besser nicht selbst in die Fensterverwaltung eingreifen, sondern lieber die Methoden verwenden, die dafür vorgesehen sind. Im Idealfall über einen eigene Container-Viewcontroller-Klasse oder über UIViewControllerAnimatedTransitioning.

    BTW: Ich würde in iOS von der direkten Manipulationen auf Fenstern möglichst die Finger lassen. Es gibt eigentlich nur sehr wenige Fälle, wo das sinnvoll ist.
    „Meine Komplikation hatte eine Komplikation.“
  • Erstmal danke für deine Antwort, ich glaub du hast ein paar Sachen falsch verstanden.


    macmoonshine schrieb:

    Was soll bitte das erste Listing bewirken? Du fügst einem Fenster einen View hinzu, der sowieso schon in dem Fenster liegt. Das ist Unsinn.
    Diese View sollte angezeigt werden, richtig - das tut sie aber nach der Animation nicht mehr, deshalb der Code, der auch funktioniert, also kein Unsinn und wie ich gesagt hab sehr hardgecoded.
    Würde selbst auch gern wissen, warum diese View einfach verschwindet. (Bild wird einfach schwarz)
    Das war eigentlich meine Urpsrungsfrage :)


    macmoonshine schrieb:

    Wenn du den Wechsel zwischen Viewcontrollern selbst animieren willst, solltest du besser nicht selbst in die Fensterverwaltung eingreifen, sondern lieber die Methoden verwenden, die dafür vorgesehen sind. Im Idealfall über einen eigene Container-Viewcontroller-Klasse oder über UIViewControllerAnimatedTransitioning.
    Ich verwende für die Animation meiner Viewcontroller UIViewControllerAnimatedTransitioning.


    macmoonshine schrieb:

    BTW: Ich würde in iOS von der direkten Manipulationen auf Fenstern möglichst die Finger lassen. Es gibt eigentlich nur sehr wenige Fälle, wo das sinnvoll ist.
    Ich weiß nicht ganz genau was du damit meinst, gehe aber davon aus, dass du auf meinen Vorschlag einen Button über Programmcode auf die View zu packen, hinaus willst.


    Bioaim schrieb:

    Nachdem das Transitioning der Views aber fertig ist, springen die Buttons zurück an ihre Ursprungspositionen, was natürlich nicht gewünscht ist. (keine Ahnung ob das mit dem hardgecodeden Code zu tun hat)


    Gibt es da irgendeine andere Möglichkeit, das zu lösen?
    Da ich noch User Interaction brauche (1 Button um die Animation wieder rückgängig zu machen), fällt auch die Möglichkeit der Snapshots weg.

    Ein Lösungsweg der mir noch eingefallen wäre, weiß aber nicht ob das funktioniert:

    Ich snapshote die fromView und adde einen neuen Button auf die Content View.
    Aber: Wie funktioniert das dann mit der ButtonAction?

    Danke im Voraus schon für alle Antworten!

    LG
    Das wären meine Hauptfragen.
  • Bioaim schrieb:

    Diese View sollte angezeigt werden, richtig - das tut sie aber nach der Animation nicht mehr, deshalb der Code, der auch funktioniert, also kein Unsinn und wie ich gesagt hab sehr hardgecoded.
    Der Code aus Listing 1 ist nur dann sinnvoll, wenn deine Transition den View des Viewcontrollers aus dem Fenster entfernt. Das willst du ja anscheinend nicht. Leider hast du keinen Code für deine Transition gepostet. Ich vermute, dass das eher da zu suchen ist. Der gepostete Code ist dahingehend unsinnig, weil der View des Rootviewcontrollers automatisch zum Fenster hinzugefügt wird und bei der Trennung wieder entfernt wird.

    Du kannst natürlich auch versuchen, mit diesen inkonsistenten Zustand durch das Gefrickel zu reparieren. Das wird aber wahrscheinlich zu weiteren Problemen führen.

    Bioaim schrieb:

    Nachdem das Transitioning der Views aber fertig ist, springen die Buttons zurück an ihre Ursprungspositionen, was natürlich nicht gewünscht ist. (keine Ahnung ob das mit dem hardgecodeden Code zu tun hat)

    Gibt es da irgendeine andere Möglichkeit, das zu lösen?
    Auch hierfür wäre der eigentliche Transitionscode hilfreich, und hört sich nach einem Folgeproblem der Transition an.

    BTW: Was bedeutet genau hardgecoded und wie sind die nicht hardgecodeten Teile gecodet? Etwa soft?
    „Meine Komplikation hatte eine Komplikation.“
  • Hier der Transitioncode:

    Quellcode

    1. func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    2. let containerView = transitionContext.containerView()!
    3. let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
    4. let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
    5. let moveDown = CGAffineTransformMakeTranslation(0, 335)
    6. if isPresenting {
    7. var menuViewFrame: CGRect = toView.frame
    8. menuViewFrame.origin.y = 0 - menuViewFrame.size.height
    9. toView.frame = menuViewFrame
    10. containerView.addSubview(toView)
    11. }
    12. UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.3, options: [], animations: {
    13. if !self.isPresenting {
    14. toView.transform = CGAffineTransformIdentity
    15. fromView.transform = CGAffineTransformIdentity
    16. toView.userInteractionEnabled = true
    17. }
    18. else {
    19. toView.transform = moveDown
    20. fromView.transform = moveDown
    21. }
    22. }, completion: { finished in
    23. transitionContext.completeTransition(true)
    24. if let window = UIApplication.sharedApplication().keyWindow {
    25. if let viewController = window.rootViewController {
    26. window.addSubview(viewController.view)
    27. }
    28. }
    29. })
    30. }
    Alles anzeigen
    Hardgecoded deshalb, weil es einfach, wie du sagst, eigentlich unsinnig ist - nur hat es das Problem mit dem Verschwinden dieser View gelöst. (aber auf keinen Fall optimal gelöst!)
    Lass uns nicht weiter über das Wort "hardgecoded" diskutieren :D
  • Du solltest den View des Zielcontrollers immer zu dem Containerview hinzufügen; also auch beim Verschwinden. Damit kannst du dir dann auch die Zeilen 24 bis 28 sparen.

    Die Transformationen sehen etwas ungewöhnlich aus. Sollen sich der alte und der neue View immer in die gleiche Richtung bewegen?
    „Meine Komplikation hatte eine Komplikation.“
  • Bringt leider auch nichts.

    Hab gelesen, dass scheinbar seit iOS 8 die fromView nach der Transition gelöscht wird. Ob das ein Bug ist oder nicht, hab ich nicht wirklich herauslesen können.
    Ich brauche irgendeine Möglichkeit um diese fromView auch nach der Transition angezeigt zu bekommen und auch noch auf den Controller der View zugreifen zu können.


    Die Transformationen passen und funktionieren auch. Da ich zuerst die Position der toView über die andere setzte und dann beide gleich nach unten animiere, siehst das aus, als würde man runterscrollen.
  • Also Tansitions finden ja in einer speziellen ContainerView statt.
    Diese wird nach der Transition entfernt und der toVC dann entsprechend in die endgültige View-Hierarchie gesetzt.
    Ob der fromVC verschwindet oder nicht hängt vielleicht auch davon ab wo man die Transition verwendet.

    Wenn man z.B. in einen NavigationVC einen ViewController mit transparentem Hintergrund pushed, sieht man wie der darunterliegende VC nach dem Push verschwindet und zu Beginn des Pulls wieder erscheint.

    Bei modalen Präsentationen bleibt der fromVC mit Sicherheit erhalten.
  • Thyraz schrieb:

    Bei modalen Präsentationen bleibt der fromVC mit Sicherheit erhalten.
    Der Viewcontroller bleibt immer erhalten. In einer Navigation-Scene liegt er ja schließlich auf dem Stack. In der Regel entfernt die Transition den View aus dem Fenster, außer bei modalen Formsheet-Transitionen oder wenn man es explizit ausschaltet (m. W. Over Full Screen). Wahrscheinlich muss man aus diesem Grund das (optionale) Entfernen des alten Views über completeTransition: anstoßen und nicht über removeFromSuperview selber vornehmen.
    „Meine Komplikation hatte eine Komplikation.“
  • Die Transition verwende ich in einer ButtonAction:.

    Quellcode

    1. @IBAction func menuButtonPressed(sender: AnyObject) {
    2. //present menu view controller
    3. let menuViewController = storyboard!.instantiateViewControllerWithIdentifier("MenuTableViewController") as! MenuTableViewController
    4. menuViewController.transitioningDelegate = self
    5. navigationItem.leftBarButtonItem?.enabled = false
    6. presentViewController(menuViewController, animated: true, completion: nil)
    7. UIView.animateWithDuration(1.5, animations: {
    8. self.testButton.center.x = self.view.bounds.width / 2
    9. }, completion: { _ in
    10. //some work
    11. })
    12. }
    Alles anzeigen

    Gleichzeitig animiere ich auch einen Button auf der alten View.

    Hier nochmal der (leicht geänderte) Transitioncode:


    Quellcode

    1. func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    2. let containerView = transitionContext.containerView()!
    3. let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
    4. let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
    5. let moveDown = CGAffineTransformMakeTranslation(0, 335)
    6. if isPresenting {
    7. var menuViewFrame: CGRect = toView.frame
    8. menuViewFrame.origin.y = 0 - menuViewFrame.size.height
    9. toView.frame = menuViewFrame
    10. }
    11. containerView.addSubview(toView)
    12. UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.3, options: [], animations: {
    13. if !self.isPresenting {
    14. toView.transform = CGAffineTransformIdentity
    15. fromView.transform = CGAffineTransformIdentity
    16. }
    17. else {
    18. toView.transform = moveDown
    19. fromView.transform = moveDown
    20. }
    21. }, completion: { finished in
    22. transitionContext.completeTransition(true)
    23. if let window = UIApplication.sharedApplication().keyWindow {
    24. if let viewController = window.rootViewController {
    25. window.addSubview(viewController.view)
    26. }
    27. }
    28. })
    29. }
    Alles anzeigen
    Der alten VC nutzt einen NavigationController, der neue nicht.

    Also liegt das Problem an der View-Hierarchie. Wie kann ich den alten VC wieder da rein setzten?