web-dev-qa-db-fra.com

Ouvrez UISplitViewController en vue principale plutôt qu'en détail

J'ai une interface en mode partagé avec une application cible pour iPhone 6. Lors du premier lancement de l'application, celle-ci s'ouvre sur la vue détaillée. Je voudrais qu'il s'ouvre à la vue principale. J'ai essayé:

self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryOverlay

Ce qui a été suggéré ailleurs (Question précédente StackOverFlow) mais cela ne semble rien faire et n’ouvre pas la vue principale au lancement. J'ai également essayé d'ajouter la ligne suivante à mon AppDelegate:

splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:

Mais malgré le retour vrai ou faux ( Une autre question de débordement de pile antérieure ) je n’ai pas réussi.

J'ai lancé l'exemple d'application maître-détail dans Xcode, qui est chargé dans la vue principale en fonction de splitViewController: appel retournant false; Cependant, je ne sais pas comment faire pour que cela fonctionne dans une mise en page plus compliquée. 

18
Tom Foutz

Rapide

UISplitViewController affiche la vue principale au-dessus des détails en orientation portrait ne consiste pas à afficher la vue principale, mais à présenter la vue Détail en pleine largeur, sous la vue principale.

UISplitViewController en mode portrait sur iPhone montre les détails VC au lieu de maître concerne le principe du mécanisme de réduction.

La présente réponse concerne:

  • Master → Détail (largeur compacte)
    • iPhone 4s, 5, 5s, SE, 6, 6s, 7 (toute orientation)
    • ipod touch
    • n'importe quel iPhone Plus (portrait)
  • côte à côte (toutes les autres tailles)
    • iPad
    • n'importe quel iPhone Plus (paysage)

Vous devez définir preferredDisplayMode. Vous voudriez que soit .primaryVisibles'il existait! À l'aide de .allVisible, iOS choisit Detail si une seule vue convient (largeur compacte); dans cette taille, le code ci-dessous sélectionne Master.

L'astuce consiste à changer les deuxla preferredDisplayMode en .allVisibleetpour renvoyer true dans collapseSecondary:onto.

class PrimarySplitViewController: UISplitViewController,
                                  UISplitViewControllerDelegate {

    override func viewDidLoad() {
        self.delegate = self
        self.preferredDisplayMode = .allVisible
    }

    func splitViewController(
             _ splitViewController: UISplitViewController,
             collapseSecondary secondaryViewController: UIViewController,
             onto primaryViewController: UIViewController) -> Bool {
        // Return true to prevent UIKit from applying its default behavior
        return true 
    }
}
44
SwiftArchitect

Étape 1 - Ouvrez MasterViewController

Étape 2 - Assurez-vous que la vue Table utilise le protocole UISplitViewControllerDelegate. Par exemple: 

class ListVC: UITableViewController,UISplitViewControllerDelegate {}

Étape 3 - Ajoutez-le dans ViewDidLoad

splitViewController?.delegate = self

Étape 4 - Ensuite, substituez cette méthode pour indiquer que le contrôleur de vue principal doit toujours être réduit sur le contrôleur de vue de détail:

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
    return true
}
5
iOS Lifee

Lors du premier lancement de l'application, celle-ci s'ouvre sur la vue détaillée. Je voudrais qu'il s'ouvre au Master View

En supposant que vous ne le vouliez que lors du premier lancement, mais pas toujours; par exemple dans le cas où la vue principale affiche un ensemble de données vide; alors la solution est juste comme le modèle Master-Detail montre:

func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController:UIViewController, ontoPrimaryViewController primaryViewController:UIViewController) -> Bool {
    guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
    guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
    if topAsDetailController.detailItem == nil {
        // Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
        return true
    }
    return false
}
4
NiñoScript

C'est une question ancienne et aucune des réponses ne concernait l'Objectif C, et même lorsque j'ai porté les réponses de Swift, aucune n'a fonctionné pour moi. L'un d'entre eux était proche, de @SwiftArchitect.

Mais il a recommandé de définir le mode de contenu sur .allVisible (UISplitViewControllerDisplayModeAllVisible dans Objective C) - la vue principale est affichée tout le temps, divisant la vue en vue principale d’un côté et en détail de l’autre. Ce qui est plutôt cool, mais l’opérateur a demandé spécifiquement d’afficher la vue principale lors du lancement initial, ce que j’avais besoin de faire.

Le changement consistait à utiliser UISplitViewControllerDisplayModePrimaryOverlay pour le mode d'affichage.

Cette réponse concerne Xcode 9.4.1, cible de déploiement 11.4.

Voici MasterViewController.h - vous devez ajouter UISplitViewControllerDelegate dans la déclaration de protocole:

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "MasterDetailDemo+CoreDataModel.h"

@class DetailViewController;

@interface MasterViewController : UITableViewController
<UISplitViewControllerDelegate,
NSFetchedResultsControllerDelegate>

@property (strong, nonatomic) DetailViewController *detailViewController;

@property (strong, nonatomic) NSFetchedResultsController<Event *> *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

@end

Ensuite, dans votre MasterViewController.m, vous devez définir le délégué délégué du contrôleur de vue fractionnée et le mode contenu dans ViewDidLoad, puis la réponse de @ SwiftArchitect pour ajouter également la méthode de délégation du contrôleur de vue fractionnée:

- (void)viewDidLoad {

    [super viewDidLoad];

    // needed to "slide out" MasterView on startup on iPad
    self.splitViewController.delegate = self;
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];

    self.navigationItem.rightBarButtonItem = addButton;

    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}

// split view delegate method
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
    return true;
}

NOTE: Après quelques tests, j'ai constaté que la méthode de délégation de la vue fractionnée et le protocole de la vue fractionnée n'étaient pas nécessaires. Sans cela, il semble fonctionner exactement de la même manière. Cela est peut-être dû aux modifications apportées à iOS depuis que la question a été posée et à laquelle elle a été posée.

Je l'ai bien fonctionné juste en mettant cette ligne dans ma méthode ViewDidLoad:

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
0
ByteSlinger