Categories
français

Une fenêtre qui change de view controller

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.

Capture d’écran 2013-09-16 à 10.09.24

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:

Square Circle

 

 

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:

Capture d’écran 2013-09-16 à 09.33.27

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):

Capture d’écran 2013-09-16 à 09.42.16

Éditez CECustom0ViewController.xib. Ajoutez simplement une NSBox et fixez son titre pour savoir de quel xib il s’agit:

Capture d’écran 2013-09-16 à 09.43.50

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