web-dev-qa-db-fra.com

UISplitViewController par programmation sans nib / xib

Je crée généralement mes projets sans IB-stuff. La première chose que je fais est de supprimer toutes les références aux xibs, aux points de vente mis à jour, etc., etc. Aucun problème, fonctionne très bien (dans mon monde)!

Maintenant, je viens d'installer 3.2 et j'ai essayé de développer ma première application iPad. En suivant la même procédure que précédemment, j'ai créé un projet d'application basé sur UISplitView et supprimé tous les éléments IB. En outre, j'ai suivi la section dans les documents de référence d'Apple: Création d'un contrôleur de vue fractionnée par programme , mais néanmoins, la vue principale n'est jamais affichée, seule la vue détaillée est (quelle que soit l'orientation) . J'ai vraiment essayé de regarder attentivement, mais je ne comprends pas ce que j'ai manqué.

Existe-t-il un exemple de travail d'un UISplitViewController sans que les plumes flottent quelque part? J'ai googlé mais je n'ai pas pu en trouver. Ou savez-vous ce que j'ai probablement manqué?

47
Steve

Déclarez votre splitviewcontroller dans votre en-tête de délégué, utilisez quelque chose comme ça dans votre didfinishlaunching

assurez-vous d'ajouter UISplitViewControllerDelegate au fichier d'en-tête détailléViewController et que vous disposez également des méthodes déléguées. n'oubliez pas d'importer les fichiers d'en-tête pertinents

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{    

    splitViewController = [[UISplitViewController alloc] init];

    rootViewController *root = [[rootViewController alloc] init];
    detailedViewController *detail = [[detailedViewController alloc] init]; 

    UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:root];

    UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detail];

    splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, detailNav, nil];
    splitViewController.delegate = detail;

    [window addSubview:splitViewController.view];

EDIT - selon l'excellente suggestion de Scott ci-dessous, n'ajoutez pas à la sous-vue windows, à la place

    [self.window setRootViewController:(UIViewController*)splitViewController];  // that's the ticket
    [window makeKeyAndVisible];
    return YES;
}


//detailedView delegate methods
- (void)splitViewController:(UISplitViewController*)svc 
     willHideViewController:(UIViewController *)aViewController 
          withBarButtonItem:(UIBarButtonItem*)barButtonItem 
       forPopoverController:(UIPopoverController*)pc
{  
    [barButtonItem setTitle:@"your title"];



    self.navigationItem.leftBarButtonItem = barButtonItem;
}


- (void)splitViewController:(UISplitViewController*)svc 
     willShowViewController:(UIViewController *)aViewController 
  invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    self.navigationItem.leftBarButtonItem = nil;
}

Je préfère également le code à IB ;-)

58
Nik Burns

Un fil ancien, mais je pensais que je gagnerais plus de temps au lecteur + de problèmes lorsque la technique ci-dessus ne parvient pas à produire un UISplitViewController qui répond correctement aux événements de changement d'orientation de périphérique. Vous devrez:

  1. Assurez-vous que toutes les vues subordonnées répondent correctement dans shouldAutorotateToInterfaceOrientation. Rien de nouveau ici.
  2. Plutôt que d'ajouter la vue UISplitViewController à la fenêtre principale,

    [window addSubview:splitViewController.view];   // don't do this
    

    définissez plutôt le contrôleur racine de la fenêtre principale sur UISplitViewController:

    [self.window setRootViewController:(UIViewController*)splitViewController];  // that's the ticket
    

L'ajout de la vue de splitviewcontroller en tant que sous-vue de la fenêtre principale (à peine) lui permet de co-présenter avec les vues de frère, mais cela ne va pas avec le cas d'utilisation prévu d'UISplitViewController. Un UISplitViewController est une vue highlander; il ne peut y en avoir qu'un.

23
Scott Honji

Je venais de rencontrer le même problème. assurez-vous que votre enfant viewController de splitview peut effectuer une rotation automatique pour l'orientation de l'interface.

vous pouvez changer la fonction dans votre childViewController comme ceci:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

alors la vue principale sera affichée.

3
ziqian hu

Swift 5. version (les contrôleurs maître et détail sont intégrés dans les contrôleurs de navigation)

    let splitViewController =  UISplitViewController()
    splitViewController.delegate = self
    let masterVC = MasterViewController() 
    let detailVC = DetailViewController()
    let masterNavController = UINavigationController(rootViewController: masterVC)
    let detailNavController = UINavigationController(rootViewController: detailVC)
    splitViewController.viewControllers = [masterNavController,detailNavController]

Vous pouvez mettre ce code dans la fonction didFinishLaunchingWithOptions de votre AppDelegate. N'oubliez pas de faire du splitViewController votre rootViewController comme ceci

    self.window!.rootViewController = splitViewController
1
Bartosz Kunat