Ce billet intéressera les programmeurs débutants sur le Mac. Je vais ici vous montrer comment passer d’un panneau à un autre, chacun défini dans son propre xib et géré par une sous-classe de NSViewController.
Création du projet et mise en place de la toolbar
J’utilise Xcode 5. Commencez par créer un projet d’application pour Mac.
J’ajoute deux images de 32 x 32 pixels, qui serviront d’icônes pour la toolbar:
Xcode a créé un premier MainMenu.xib pour votre appli, comprenant une barre des menus et surtout une fenêtre.
Nous allons ajouter une NSToolbar à cette fenêtre. Pour cela, il suffit de glisser une toolbar depuis la rubrique Object Library (dans le coin inférieur droit de la fenêtre de Xcode) vers la fenêtre. La toolbar comporte déjà des icônes. Configurez-la pour qu’elle présente deux icônes en son centre:
Pour cela, supprimez tous les NSToolbarItems présents, glissez de nouveaux items, puis configurez-les.
Maintenant, tirez des actions allant de chaque icône vers l’AppDelegate.
@interface CEAppDelegate : NSObject <NSApplicationDelegate> @property (assign) IBOutlet NSWindow *window; - (IBAction)item0Pushed:(NSToolbarItem *)sender; - (IBAction)item1Pushed:(NSToolbarItem *)sender; @end
Création des panneaux
Chaque panneau sera géré par un view controller et sera contenu dans un xib.
Commencez par créer une sous-classe de NSViewController (que j’appelle CECustom0ViewController):
Éditez CECustom0ViewController.xib. Ajoutez simplement une NSBox et fixez son titre pour savoir de quel xib il s’agit:
Créez une deuxième sous-classe de NSViewController sur le même principe (CECustom1ViewController).
Passage d’un view controller à l’autre
Pour gérer le changement de view controller, je créé une classe CEViewControllerSwitcher, qui hérite de NSObject:
CEViewControllerSwitcher.h
#import <Foundation/Foundation.h> @interface CEViewControllerSwitcher : NSObject - (id) initWithParentView:(NSView *)parentView viewControllers:(NSArray *)viewControllers; @property (nonatomic, assign) NSUInteger viewControllerIndex; @end
CEViewControllerSwitcher.m
#import "CEViewControllerSwitcher.h" @interface CEViewControllerSwitcher () @property (strong) NSView *parentView; @property (strong) NSArray *viewControllers; @property (weak) NSViewController *currentViewController; @end @implementation CEViewControllerSwitcher - (id) initWithParentView:(NSView *)parentView viewControllers:(NSArray *)viewControllers { self = [super init]; if (self) { _parentView = parentView; _viewControllers = viewControllers; self.viewControllerIndex = 0; // Afficher le premier VC au départ } return self; } - (void) setViewControllerIndex:(NSUInteger)viewControllerIndex { _viewControllerIndex = viewControllerIndex; // Retirer le VC précédent if(self.currentViewController) { [self.currentViewController.view removeFromSuperview]; } // Ajouter le nouveau VC self.currentViewController = [self.viewControllers objectAtIndex:viewControllerIndex]; [self.parentView addSubview:self.currentViewController.view]; } @end
Liaison avec l’AppDelegate
CEAppDelegate.m
#import "CEAppDelegate.h" #import "CEViewControllerSwitcher.h" #import "CECustom0ViewController.h" #import "CECustom1ViewController.h" @interface CEAppDelegate () @property (strong, nonatomic) CEViewControllerSwitcher *viewControllerSwitcher; @end @implementation CEAppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSView *contentView = self.window.contentView; CECustom0ViewController *viewController0 = [[CECustom0ViewController alloc] initWithNibName:@"CECustom0ViewController" bundle:nil]; CECustom1ViewController *viewController1 = [[CECustom1ViewController alloc] initWithNibName:@"CECustom1ViewController" bundle:nil]; self.viewControllerSwitcher = [[CEViewControllerSwitcher alloc] initWithParentView:contentView viewControllers:[NSArray arrayWithObjects:viewController0, viewController1, nil]]; } - (IBAction)item0Pushed:(NSToolbarItem *)sender { self.viewControllerSwitcher.viewControllerIndex = 0; } - (IBAction)item1Pushed:(NSToolbarItem *)sender { self.viewControllerSwitcher.viewControllerIndex = 1; } @end
C’est terminé !
Voilà, ça fonctionne, on passe bien d’un View Controller à l’autre. Il s’agissait de la technique de base, je vous laisse régler l’autolayout des vues pour qu’elles remplissent bien la contentView de la fenêtre comme on le souhaite.
Le projet Xcode complet: ChangeVues