web-dev-qa-db-fra.com

Détendez-vous Segue ne fonctionne pas dans iOS 8

J'ai une application qui fonctionne très bien sous iOS 7, mais une fois conçue pour iOS 8, les segments de déroulement ne fonctionnent pas.

J'ai créé un nouveau projet et ajouté un modal (navigationcontroller avec tableviewcontroller) et essayé d'utiliser un modal de déroulement. Malheureusement, ça ne marche pas non plus. Les méthodes en cours de décompression se trouvent dans le contrôleur de vue de dessination. La séquence de déroulement est créée via le scénario (un bouton de la barre de navigation dans le contrôleur tableview). Lorsque je touche le bouton, rien ne se passe. Il n'y a pas de journal de sortie et le modal ne disparaît pas. De plus, cela ne semble toucher que les divisions modales. Push/Popover sont déroulés normalement.

Quelqu'un at-il eu un problème similaire et a une idée de la façon dont je pourrais le résoudre?

66
viirus

Apple a corrigé ce bogue dans iOS 8.1

Solutions temporaires pour iOS 8.

La séquence de déroulement ne fonctionnera pas seulement dans la situation suivante:

Structure de la vue: ITabBarController -> INagivationController -> IViewController1 -> IViewController2

Normalement (sous iOS 7, 8.1), lors du déroulement de IViewController2 à IViewController1, il appellera viewControllerForUnwindSegueAction in IViewController1 .

Cependant, dans iOS 8.0 et 8.0.x, il appellera viewControllerForUnwindSegueAction dans ITabBarController au lieu de IViewController1, c’est la raison pour laquelle l’élimination de la séquence ne fonctionne plus.

Solution: écrasement viewControllerForUnwindSegueAction dans ITabBarController en créant une coutume ITabBarController et utilisez la coutume.

Pour Swift

CustomTabBarController.Swift

import UIKit

class CustomTabBarController: UITabBarController {

    override func viewControllerForUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject?) -> UIViewController? {
        var resultVC = self.selectedViewController?.viewControllerForUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender)
        return resultVC
    }

}

pour l'ancienne école Objective-C

CustomTabBarController.h

#import <UIKit/UIKit.h>

@interface CustomTabBarController : UITabBarController

@end

CustomTabBarController.m

#import "CustomTabBarController.h"

@interface CustomTabBarController ()

@end

@implementation CustomTabBarController

    -(UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
    {
        return [self.selectedViewController viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];
    }

@end

=============================================== ============================

N'UTILISEZ AUCUNE SOLUTION AU-DESSOUS DE CE POINT (elles sont obsolètes et juste pour référence)

dernière mise à jour le 23 septembre

Ma nouvelle solution insère une vue intégrée dans un contrôleur de navigation et le configure pour masquer la barre inférieure de Push (une case à cocher dans IB). Vous obtiendrez alors une vue ressemblant à une vue modale, le seul différent est l’animation de pousser et de sauter. Vous pouvez le personnaliser si vous voulez

Mise à jour: La solution ci-dessous présente réellement le vue modale sous le barre d'onglets, ce qui entraînera d'autres problèmes de présentation de la vue.

Changez le type de séquence en Present As Popover ne fonctionnera que sur iOS8 pour iPhone, sur iOS7 votre application plantera .

Pareil pour résoudre ce problème, j’ai replacé la présentation de segue dans son contexte actuel (mon application est uniquement pour iPhone).

Par défaut et plein écran ne fonctionnera pas.

enter image description here

60
Stewart Hou

[ UPDATE : Bug corrigé sur iOS 8.1 bêta mais vous en aurez besoin pour la prise en charge des versions 8.0 et 8.0.2]

La seule façon dont je pouvais faire en sorte que mon problème soit résolu était de mélanger les réponses d'Aditya et de viirus.

Ma configuration va dans: [View Controller 1]> séquence modale personnalisée> [Navigation Controller]> root> [View Controller 2]

Dérouler: [Contrôleur de vue 2]> séquence de déroulement personnalisée> [Contrôleur de vue 1]

Correction: sous-classe du [Contrôleur de navigation], ajoutez une propriété appelée sourceViewController et transmettez "self" à cette propriété lorsque la préparation de la séquence est appelée lors du passage de [View Controller 1] à [Navigation Controller]

Dans la sous-classe [Navigation Controller] .m, remplacez/ajoutez ces deux méthodes:

- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
{

    if ([self.sourceViewController canPerformUnwindSegueAction:action fromViewController:fromViewController withSender:sender]) {
    return self.sourceViewController;
    }
    return [super viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];   
}

Ensuite, je remplace cette information dans cette sous-classe [Contrôleur de navigation] uniquement parce que j'ai un déroulement personnalisé:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
   return [fromViewController segueForUnwindingToViewController:toViewController
                                          fromViewController:fromViewController
                                                  identifier:identifier];
}
9
Raul Rea

C'est un problème avec iOS 8.0, 8.0.1 et 8.0.2. Cela a été résolu en 8.1; Des parties déroulantes appellent maintenant la méthode appropriée.

Notez que sur iOS 8, contrairement aux iOS 7, les contrôleurs de vue présentés sous forme modale peuvent ne pas être automatiquement supprimés lors de la séquence de déroulement. Pour vous assurer qu'il est toujours ignoré, vous pouvez le détecter et, le cas échéant, le supprimer manuellement. Ces incohérences sont résolues dans iOS 9.0.

Avec iOS 8.4 exécuté sur iPhone, toutes les séquences présentées de manière modale avec tous les styles de présentation sont rejetées lors du déroulement, à l'exception du mode Plein écran et du contexte Surintensité. C'est également le cas pour l'iPad, avec l'ajout de Feuille de formulaire et Feuille de page, qui ne se supprime pas automatiquement. Avec iOS 9, tous les styles de présentation sont automatiquement supprimés sur iPhone et iPad.

6
Jordan H

Oui, cela m'est arrivé un peu aussi, je pense que dans votre cas, vous devez sous-classer UINavigationController et remplacer les éléments suivants:

    - (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
    {

        for(UIViewController *vc in self.viewControllers){
            // Always use -canPerformUnwindSegueAction:fromViewController:withSender:
            // to determine if a view controller wants to handle an unwind action.
            if ([vc canPerformUnwindSegueAction:action fromViewController:fromViewController withSender:sender])
                return vc;
                }


        return [super viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];
    }
4
Aditya Wirayudha

Woah là-bas! Je reçois toujours des rapports d'utilisateurs se bloquant sur une vue modale dans iOS 8.1.1 (sur un iPad 3).

Je suis en train de larguer tout ça pour me détendre d'une vue modale. Juste un bon vieux démodé ...

[self dismissViewControllerAnimated:NO completion:nil];

... fonctionne bien sur toutes ces différentes versions d'iOS 8.x.x.

3
Paul Brady

Il semble qu'iOS 7.1 et iOS 8.1/8.2 créent un segment de déroulement à partir du contrôleur de navigation, bien que ce dernier soit enregistré sur un contrôleur enfant à l'intérieur du contrôleur de navigation.

Donc, créer manuellement une séquence de déroulement à partir du contrôleur où il est enregistré dans le storyboard résout le problème.

@implementation RootNavigationController

- (UIStoryboardSegue*)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
    return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}

@end
3
highmaintenance

Même problème ici. La méthode Unwind n'est pas appelée. Cela n'arrive que lorsque

  • en utilisant le mode modal
  • La présentation est tout sauf "contexte actuel"
  • NavigationController n'est pas étendu (utilisation des paramètres par défaut du storyboard)

Cela se produit également dans IOS8 GM Graine, par conséquent, je pense que nous devons trouver une solution de contournement. Cela ressemble à un bogue pour moi ...

L'extension de UINavigationController et la mise en œuvre de viewControllerForUnwindSegueAction n'ont pas aidé, car elles ne sont pas déclenchées. La seule chose qui se déclenche est canPerformUnwindSegueAction () dans UINavigationController étendu. Étrange.

3
Bertl

J'ai rencontré le même problème lors du déroulement sur un contrôleur de vue source à partir d'un contrôleur de vue de destination. La destination a été présentée à travers une émission "spectacle" de la source. J'utilisais un simulateur iPhone qui montre iPhone 6, iOS8.3. XCode 6.3.2

La solution de sous-classement de NavigationViewController a fonctionné pour moi. Voici le Swift qui est essentiellement Swift de la réponse de Raul. Je suis perplexe que si Apple l'a corrigé dans iOS8.1 par Raul, comment suis-je touché par cela en 8.3.

var sourceViewController: UIViewController?
override func viewControllerForUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject?) -> UIViewController? {
        if(self.sourceViewController! .canPerformUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender!)){
            return self.sourceViewController
        }
        return super.viewControllerForUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender)
    }
1
Jitendra Kulkarni

Je viens de rencontrer ce problème, et après quelques recherches, nous avons découvert qu'avec les séquences modales (du moins celles avec les modes de présentation par défaut et plein écran), vous ne pouvez pas vous fier au mécanisme de déroulement normal, mais vous devez appeler la méthode de renvoi ViewController de UIViewController présentée. méthode.

0
user3483058