2010-09-23 8 views
0

Je souhaite utiliser une vue modale (UIViewController) comme vue "normale", qui peut être poussée sur la pile du contrôleur de navigation. Normalement, une vue modale est présenté comme ceci:Utiliser la vue modale comme vue "normale"

LoginViewController *myView = [[MyViewController alloc] init]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView]; 
[self.navigationController presentModalViewController:navController animated:YES]; 
[myView release]; 
myView = nil; 
[navController release]; 
navController = nil; 

Mais je veux faire quelque chose comme ceci:

[[self navigationController] pushViewController:myView animated:YES]; 

Le problème est que mon point de vue modal a un droit et un bouton gauche. Donc je devrais vérifier comment la vue est chargée et présenter les boutons d'une autre manière. L'idée derrière cela est d'avoir le bouton de retour. Donc, je peux utiliser la même vue modale à quelques reprises.

Edit:

@petert:

Maintenant j'ai suivi votre exemple. Mon problème est que j'utilise un UINavigationBar pour la vue modale. Pour obtenir ce UINavigationBar je crée un contrôleur de navigation. J'utilise la barre de navigation parce que j'ai mes boutons dedans. Donc, vérifier si parentViewController est de type UINavigationController ne fonctionne pas pour moi. Je reçois toujours une vue modale. Voici comment je le fais:

// load modal view 
MyViewController *myView = [[MyViewController alloc] init]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView]; 
[[self navigationController] presentModalViewController:navController animated:YES]; 
[navController release]; 
navController = nil; 
[myView release]; 
myView = nil; 


// load as normal view 
MyViewController *myView = [[MyViewController alloc] init]; 
[[self navigationController] pushViewController:myView animated:YES]; 

Répondre

2

Bons conseils dans ce StackOverflow answer.

Je préfère utiliser la propriété de UIViewController:

@property(nonatomic, readonly) UIViewController *parentViewController 

dans la sous-classe d'un contrôleur de vue:

Regardez la valeur de la propriété parentViewController du contrôleur. S'il s'agit d'une instance de UINavigationController, vous êtes dans la pile de navigation. Si vous êtes affiché de manière modale, ce sera une instance de votre dernier contrôleur de vue.

Ainsi, dans -viewDidLoad par exemple:

- (void)viewDidLoad 
{ 
    if ([self.parentViewController isKindOfClass:[UINavigationController class]]) 
    { 
     // navigation controller 
     self.title = @"..."; 
    } 
    else 
    { 
     // modal 
     self.title = @"Modal"; 

     // add cancel and done buttons now... 
    } 
} 

Ou, une solution assez simple serait de personnaliser votre méthode init à votre classe MyViewController pour coder votre intention pour le contrôleur de vue.

Ajouter ce qui suit à l'en-tête MyViewController:

@interface MyViewController : UIViewController 
{ 
    BOOL modal; 
} 

- (id)initForModal:(BOOL)isModal; 

@end 

maintenant dans le fichier de mise en œuvre:

@interface MyViewController() 
@property (nonatomic) BOOL modal; 
@end 

@implementation MyViewController 

@synthesize modal; 

- (id)initForModal:(BOOL)isModal; 
{ 
    if (self = [super initWithNibName:@"MyViewController" bundle:nil]) 
    { 
     self.modal = isModal; 
    } 

    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    if (self.modal) 
    { 
     // add cancel and done buttons … 
    } 
    else 
    { 
     // assuming we're presented from a navigation view … 
    } 
} 

maintenant à utiliser cette façon modale:

// load modal view 
MyViewController *myView = [[MyViewController alloc] initForModal:YES]; 

Ou pas modalement:

// load as normal view 
MyViewController *myView = [[MyViewController alloc] initForModal:NO]; 

Je suppose que vous créez les contrôleurs de vue à partir de NIB, mais comme toujours voir le View Controller Progamming Guide for iOS et en particulier la section intitulée «Définition d'une classe contrôleur de vue personnalisé».

+0

Merci pour votre code fourni d'échantillon. Je pense que cela fonctionnerait bien, mais j'utilise un 'UINavigationController' pour présenter ma vue modale. Pourquoi je le fais est expliqué dans ma question éditée. Peut-être pourriez-vous fournir une solution. – testing

+0

Votre soutien est formidable! Cette solution est assez simple et fonctionne bien. Maintenant quelques questions pour ma compréhension: 1) Pourquoi font une nouvelle déclaration d'interface dans le fichier de mise en œuvre? 2) Le 'if' dans le' initForModal' appelle le super constructeur et s'il réussit, il renvoie l'objet ('ViewController') et sinon il renvoie nil. Est-ce correct? Dans l'instruction 'if', seule une option est définie si l'objet n'est pas nul. 3) J'ai besoin de la propriété ici parce que la variable est utilisée au-dessus des limites de la méthode? – testing

+0

Heureux que ce soit utile - 1) c'est de cacher la propriété modale, puisque ce n'est pas pour une utilisation en dehors de cette implémentation de classes; 2) Oui, absolument, c'est un style obj-c général pour les méthodes init; 3) J'ai utilisé une propriété juste pour simplifier les choses, je pense que la réponse à votre question est oui? N'oubliez pas de voter la réponse aussi, si c'est aidé, merci. – petert

0

Pour clarification: myView n'est pas modal. Vous venez de le présenter comme un modal.

Si vous le poussez simplement dans une hiérarchie UINavigationController, il se comportera comme un "normal".

Vous ne pouvez pas pousser le même contrôleur de vue sur la pile de navigation plusieurs fois. Juste une fois.

Voir aussi ce sur la façon de personnaliser l'affichage:

SO modal question

+0

OK, je le présente comme vue modale. Avez-vous un exemple pour une "vraie" vue modale? Je ne veux pas le pousser en même temps sur la pile. Que voulez-vous dire avec juste une fois? Je peux le mettre comme vue normale sur la pile, mais plus tard, pas comme vue modale? – testing

Questions connexes