52 votes

Contrôleurs de vues: comment basculer entre les vues par programmation?

En bref: je veux avoir deux vues en plein écran, où je peux basculer entre Une vue et vue B. je sais que je pouvais utiliser la Barre d'onglets de contrôle, mais je ne veux pas. Je veux voir comment c'est fait à la main, pour l'apprentissage de ce qui se passe sous le capot.

J'ai un UIViewController qui agit comme une racine contrôleur:

@interface MyRootController : UIViewController {
    IBOutlet UIView *contentView;
}
@property(nonatomic, retain) UIView *contentView;

@end

Le contentView est relié à une UIView laquelle j'ai ajouté une sous-vue de la "vue" de la Plume. Cela a la couleur verte et je vois plein écran. Fonctionne très bien.

Ensuite, j'ai créé deux autres Contrôleurs de Vue peu de la même manière. ViewControllerA et ViewControllerB. ViewControllerA a un fond bleu, ViewControllerB a un arrière-plan noir. Juste pour voir celui qui est actif.

Ainsi, dans la mise en œuvre de myRootController, je fais ceci:

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    ViewControllerA *vcA = [[ViewControllerA alloc] initWithNib];
    [self.contentView addSubview:vcA.view];

    [cvA release];
}

Par ailleurs, l'-initWithNib méthode ressemble à ceci:

- (id)initWithNib { // Load the view nib
    if (self = [super initWithNibName:@"ViewA" bundle:nil]) {
        // do ivar initialization here, if needed
    }
    return self;
}

Qui fonctionne. Je vois le point de vue de ViewControllerA lors du démarrage de l'application. Mais maintenant, la grande question est: A-Vue-Contrôleur généralement toutes ces méthodes comme:

  • (void)viewWillAppear:(BOOL)d'animation;
  • (void)viewDidDisappear:(BOOL)d'animation;
  • (void)viewDidLoad;

...et ainsi de suite. De qui ou de quoi, ou comment ces méthodes de l'appeler si je le fais "mon" chemin sans un onglet de la barre de contrôleur? Je veux dire: Si j'alloue que ViewController de la classe et la vue est visible, aurais-je prendre soin de l'appel de ces méthodes? Comment sait-elle que viewWillAppear, viewDidDisappear, ou viewDidLoad? Je crois que la Barre d'Onglet Contrôleur a tous cette "intelligence" sous le capot. Ou je me trompe?

Mise à JOUR: je l'ai testé. Si je dégage la vue-contrôleur (par exemple: ViewControllerA), je n'aurez pas de message de journal sur viewDidDisappear. Seulement lors de l'allocation et initialisation de la ViewControllerA, je reçois un viewDidLoad. Mais c'est tout. Donc, tous les signes de stand pour l'intelligence de UITabBarController maintenant ;) et je dois trouver comment reproduire ça, hein?

50voto

nevan king Points 46410

Vous trouverez un bon exemple de changement de vue au chapitre 6 du manuel Développement de l'iPhone. Vous pouvez voir le code source pour cela ici: http://iphonedevbook.com/

SwitchViewController a le code pour changer les vues par programme.

 
- (IBAction)switchViews:(id)sender
{

    if (self.yellowViewController == nil)
    {
    	YellowViewController *yellowController = [[YellowViewController alloc]
                initWithNibName:@"YellowView" bundle:nil];
    	self.yellowViewController = yellowController;
    	[yellowController release];
    }

    [UIView beginAnimations:@"View Flip" context:nil];
    [UIView setAnimationDuration:1.25];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    UIViewController *coming = nil;
    UIViewController *going = nil;
    UIViewAnimationTransition transition;

    if (self.blueViewController.view.superview == nil) 
    {	
    	coming = blueViewController;
    	going = yellowViewController;
    	transition = UIViewAnimationTransitionFlipFromLeft;
    }
    else
    {
    	coming = yellowViewController;
    	going = blueViewController;
    	transition = UIViewAnimationTransitionFlipFromRight;
    }

    [UIView setAnimationTransition: transition forView:self.view cache:YES];
    [coming viewWillAppear:YES];
    [going viewWillDisappear:YES];
    [going.view removeFromSuperview];
    [self.view insertSubview: coming.view atIndex:0];
    [going viewDidDisappear:YES];
    [coming viewDidAppear:YES];

    [UIView commitAnimations];

}
 

39voto

iPhoney Points 5473

Vous pouvez commencer à partir du plus simple removeFromSuperview / insertSubview et y ajouter petit à petit du code.

 
//SwitchViewController.h
#import 
@class BlueViewController;
@class YellowViewController;

@interface SwitchViewController : UIViewController {
    IBOutlet BlueViewController *blueViewController;
    IBOutlet YellowViewController *yellowViewController;
}
- (IBAction)switchViews:(id)sender;
@property (nonatomic, retain) BlueViewController *blueViewController;
@property (nonatomic, retain) YellowViewController *yellowViewController;
@end
 
 
//1. remove yellow view and insert blue view
- (IBAction)switchViews:(id)sender {
    if(self.blueViewController.view.superview == nil)
    {
    	[yellowViewController.view removeFromSuperview];
    	[self.view insertSubview:blueViewController.view atIndex:0];
    }
}

//2. appear=insert, disappear=remove
if(blueViewController.view.superview == nil)
{
    [blueViewController viewWillAppear:YES];
    [yellowViewController viewWillDisappear:YES];

    [yellowViewController.view removeFromSuperview];
    [self.view insertSubview:self.blueViewController.view atIndex:0];

    [yellowViewController viewDidDisappear:YES];
    [blueViewController viewDidAppear:YES];
}

//3. now add animation
[UIView beginAnimations:@"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//blue view will appear by flipping from right
if(blueViewController.view.superview == nil)
{
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight 
    						forView:self.view cache:YES];

    [blueViewController viewWillAppear:YES];
    [yellowViewController viewWillDisappear:YES];

    [yellowViewController.view removeFromSuperview];
    [self.view insertSubview:self.blueViewController.view atIndex:0];

    [yellowViewController viewDidDisappear:YES];
    [blueViewController viewDidAppear:YES];
}
[UIView commitAnimations];

 

21voto

Pablo Santa Cruz Points 73944

Si je comprends bien, ce que vous essayez d'accomplir, c'est assez simple.

Il suffit d'ajouter un UINavigationController sur votre application déléguer et à faire:

[navigationController pushView:vcA];

Les délégués seront appelés en conséquence:

  • (void)viewWillAppear:(BOOL)d'animation;
  • (void)viewDidDisappear:(BOOL)d'animation;
  • (void)viewDidLoad;

Et quand vous voulez, à la pop de la vue et de pousser un autre:

[navigationController popViewControllerAnimated:true];
[navigationController pushView:vcB];

Si vous ne voulez pas le navigationController montrant simplement utiliser:

[navigationBar setHidden:YES];

Où navigationBar est le UINavigationBar correspondant à votre UINavigationController.

2voto

Ryan Artecona Points 1750

Ce peut-être un vieux problème, mais je suis récemment tombé sur le même problème et a eu un moment difficile de trouver quelque chose qui a travaillé. Je voulais passer entre les deux complémentaires contrôleurs de vue, mais je voulais le commutateur à être animé (construit dans les animations fonctionnent bien), et je voulais qu'il soit compatible avec les storyboards si possible.

Pour profiter de transition, UIView de l' +transitionFromView:toView:duration:options:completion: méthode fonctionne à merveille. Mais, il ne les transitions entre les points de vue, pas de vue sur les contrôleurs.

Pour la transition entre le point de vue des contrôleurs, pas seulement les points de vue, la création d'une coutume UIStoryboardSegue est le chemin à parcourir. Si vous utilisez des story-boards, cette approche permet d'encapsuler l'ensemble de la transition et de gérer le passage de l'information pertinente à partir d'un point de vue contrôleur à l'autre. Il s'agit uniquement de sous-classement UIStoryboardSegue et remplacement d'une méthode unique, -perform.

Pour une implémentation de référence, reportez - RAFlipReplaceSegue, l'exacte personnalisé segue j'ai mis en place à l'aide de cette approche. Comme un bonus, elle remplace l'ancienne-vue-contrôleur avec la nouvelle si c'est dans un UINavigationController de la pile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X