web-dev-qa-db-fra.com

Dans iOS 9, pourquoi SFSafariViewController est-il poussé au lieu d'être présenté de manière modale?

Je présente un SFSafariViewController en appelant presentViewController:animated:completion: sur une instance UIViewController.

Le résultat est qu'il obtient poussé (glisse depuis la droite), comme si j'appelais pushViewController:animated: sur une instance UINavigationController. J'ai vérifié que tout cela se passe dans la file d'attente principale. Et le contrôleur de vue présenté n'est pas un modal lui-même (ce qui ne devrait pas avoir d'importance de toute façon, mais juste au cas où, nous pouvons l'exclure).

Si je remplace le SFSafariViewController par un UIViewController, cela fonctionne comme prévu, il se présente de façon modale.

weakSelf.oAuthViewController = [[SFSafariViewController alloc] initWithURL:url];
[viewController presentViewController:weakSelf.oAuthViewController animated:YES completion:nil];

Une idée pourquoi ou comment contourner ce problème?

34
guptron

Voici un moyen simple d'obtenir une présentation modale verticale d'un SFSafariViewController:

let safari = SFSafariViewController(URL: url)
safari.modalPresentationStyle = .overFullScreen
presentViewController(safari, animated: true, completion: nil)
43
jamesk

Je viens d'avoir le même problème. En outre, le bouton terminé fonctionne même si vous ne configurez pas le délégué. Je ne sais pas pourquoi cela se produit. Cependant, j'ai trouvé une solution de contournement: envelopper le contrôleur safari dans un contrôleur de navigation et masquer la barre de navigation.

func openURL(url:NSURL) {

    if #available(iOS 9.0, *) {
        let safariController = SFSafariViewController(url: url)
        safariController.delegate = self
        let navigationController = UINavigationController(rootViewController: safariController)
        navigationController.setNavigationBarHidden(true, animated: false)
        self.present(navigationController, animated: true, completion: nil)
    } else {
        UIApplication.sharedApplication().openURL(url)
    }
}
24
iGerms

Pour utiliser le style de transition modale par défaut, vous pouvez simplement définir le délégué de transition égal à self.

let svc = SFSafariViewController(url: url)
svc.transitioningDelegate = self //use default modal presentation instead of Push
present(svc, animated: true, completion: nil)

Vous devrez adopter le protocole UIViewControllerTransitioningDelegate dans votre contrôleur de vue, mais il n'y a aucune fonction requise à implémenter.

Cela a été mentionné dans Session 225 à WWDC, Quoi de neuf dans Safari View Controller .

12
Jordan H

Version Objective-C de iGerms:

-(void)openURL:(NSURL *)url {
   SFSafariViewController *safariController = [[SFSafariViewController alloc]initWithURL:url];
   safariController.delegate = self;
   UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:safariController];
   [navigationController setNavigationBarHidden:YES animated:NO];
   [self presentViewController:navigationController animated:YES completion:nil];
}
7
Mark Bourke