web-dev-qa-db-fra.com

UISplitViewController: Comment forcer l'affichage du popover principal lors du lancement de l'application? (portrait)

Dans une application iPad, j'utilise UISplitViewController . Je dois forcer l'affichage du popover principal lorsque l'application démarre en mode portrait.

Maintenant, j'utilise ce code et cela fonctionne bien sur iOS 5.0. 

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
   if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) {
      [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]];
   }            
}

Mais sous iOS 5.1 (avec le nouveau type de maître popover), le comportement semble être aléatoire. Parfois, le popover s'affiche en plein écran et fonctionne parfois bien.

Une suggestion pour 5.1?

25
alejandromp

Je me suis battu avec celui-ci pendant un moment, et même maintenant, je ne suis pas entièrement satisfait de la solution, mais c'est la seule chose que j'ai pu trouver, étant donné les contraintes actuelles.

Commencez par remplacer la méthode déléguée suivante:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

et utilisez-le pour saisir une référence à l'élément bouton de barre et stockez-la dans une iVar:

barButtonForMaster = barButtonItem;

Ensuite, lorsque vous souhaitez afficher le contrôleur de vue principal, effectuez un appel comme suit:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster];

Si vous souhaitez exécuter cela dès le début, utilisez un certain délai pour éviter le blocage de l'application (grâce au commentaire utile):

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1];

Dans ce cas, vous pouvez utiliser le sélecteur directement dans la méthode de délégation de la vue fractionnée.

13
Rob Elkin

Aucune suggestion ici pour 5.1, mais une pour 8.0:

Maintenant, avec iOS8, il y a un tas de nouvelles méthodes pour la configuration UISplitViewController.

Dans votre cas, définissez juste la bonne valeur dans preferredDisplayMode, par exemple dans le maîtreViewViewer viewDidLoad.

Objectif c:

- (void)viewDidLoad {
    // configuring splitviewcontroller
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    //....
}

Rapide:

    override func viewDidLoad() {
        self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
    }

Mais ce n'est bien sûr que iOS8.

26
Martin

En prolongeant la réponse de Rob, cela fonctionne bien pour moi (dans l’écran viewDidLoad of detail):

//If in portrait mode, display the master view
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem];
}

Pas besoin d'extraire une référence séparée, en utilisant self.navigationItem.leftBarButtonItem

13
Setomidor

Pour iOS8, le moyen le plus simple consiste à:

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

J'utilise cette application lorsque l'application est lancée pour la première fois pour indiquer la connexion à masterViewController . Dans tous les autres cas, j'utilise 

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic
7
aquarius68

Si vous en avez besoin au lancement de l'application, remplacez cette méthode dans votre contrôleur de vue de détail:

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return NO;
}

Cependant, si vous en avez besoin ensuite pour le masquer, cela donne l'impression que la méthode n'est pas appelée.

5
SeanR

Une variation légèrement moins hacky (Swift):

let btn = self.splitViewController!.displayModeButtonItem()
btn.target?.performSelector(btn.action, withObject: btn)
1
maniek

J'utilise cette solution:
Dans splitViewController dans viewDidLoad, définissez displayMode sur .primaryOverlay

override func viewDidLoad() {
    if self.isCollapsed == false, self.displayMode == .primaryHidden {
        self.preferredDisplayMode = .primaryOverlay
    }
}

Et dans viewWillAppear, redéfinissez-le sur .automatic

override func viewWillAppear(_ animated: Bool) {
    self.preferredDisplayMode = .automatic
}

De cette façon, la vue principale sera affichée au lancement de UISplitViewController et aura un comportement par défaut après le changement d'orientation.

1
Alexey Saechnikov

Pas besoin de garder des références stupides autour de barButtonItem. Appelez simplement la même cible/action. Voir ma réponse https://stackoverflow.com/a/25695923/1021430

La cible est le contrôleur de vue fractionnée et l'action est toggleMasterVisible:

0
user1021430