29 votes

iOS: comportement addSubview différent entre iOS 4.3 et 5.0

lors de l'encodage dans iOS 4.3 avant, j'ai trouvé tout ajouter une vue du contrôleur de vue d'un autre point de vue avec [superview addSubView:controller.view], l'instance du contrôleur ne recevra pas l' -viewWillAppear/viewDidAppear message, que j'ai trouvé le même problème dans certains thread dans le débordement de la pile. Après, j'ai manuellement appel -viewWillAppear/-viewDidAppear en tant que de besoin.

mais, après la mise à niveau d' iOS 5.0, certains fringants UIView comportement qui s'est passé. Finalement, j'ai trouvé que dans iOS 5, l' [superview addSubView:controller.view] , envoyer une -viewWillAppear/-viewDidAppear message à l'instance du contrôleur automatiquement, de plus, mon manuellement des appels, il y a deux dupliqué message à chaque fois que le contrôleur de l'action de son comportement.

et j'ai aussi trouvé un problème similaire: iOS 5 : -viewWillAppear n'est pas appelé après la destitution de la modale de l'iPad

Maintenant, le problème est que, après la recherche d'apple documents, je n'ai pas trouvé explicitement doc pour diff sur ces questions. Je me demande même si c'est une garantie de vue du cycle de vie du comportement dans la version 5.0 d'iOS .

Personne ne résoudre des problèmes similaires ou trouver des lignes directrices au sujet de ces choses. parce que je veux exécuter mon application à la fois, en 4.x & 5.x iOS.

28voto

chris Points 6000

Dans iOS 4 vous avait manuellement appel -viewWillAppear, -viewWillDisappear, etc. lors de l'ajout ou de la suppression d'une vue à partir de votre point de vue de la hiérarchie. Ceux-ci sont appelés automatiquement dans iOS 5 si le point de vue est en train d'être ajoutés ou supprimés à partir de la fenêtre de hiérarchie. Heureusement, iOS 5 est une méthode en UIViewController que vous pouvez modifier pour rétablir le comportement de retour à la façon dont il a travaillé avec iOS 4. Juste ajouter ceci à votre UIViewController:

-(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
   return NO;
}

C'est probablement la solution la plus facile aussi longtemps que vous êtes soutenir à la fois l'iOS 4 et iOS 5. Une fois que vous déposez un soutien pour iOS 4, vous pourriez envisager de modifier votre code pour utiliser une approche plus récente lors d'échange de vues.

Edit 5 Février 2012

Apparemment cette fonction nécessite l'enfant-vue-contrôleur être ajouté à la vue principale du contrôleur à l'aide de l' addChildViewController: méthode. Cette méthode n'existe pas dans la version iOS4, de sorte que vous besoin de faire quelque chose comme ceci:

  if ([self respondsToSelector:@selector(addChildViewController:)] ) {
     [self addChildViewController:childViewController];
  }

Merci à tous ceux qui me corrige sur ce point.

9voto

hiroshi Points 1796

C'est peut-être pas répondre à ce que vous voulez, mais j'ai eu le même genre de problème.

Dans mon cas, lorsque j'ai ajouté un point de vue du contrôleur de vue d'un autre point de vue du contrôleur de la vue comme une sous-vue, la sous-vue a été reçu viewWillAppear seulement en iOS 5.0 pas l'iOS 4.X.

J'ai donc ajouté un sale état.

[self.view addSubview:self.viewController.view];
if ([[[UIDevice currentDevice] systemVersion] compare:@"5.0"] == NSOrderedAscending) {
    [self.viewController viewWillAppear:animated];
}

À partir de la version 5.0 d'iOS, Apple fournit un moyen de mettre en œuvre conteneur personnalisé afficher les contrôleurs comme UINavigationController ou UITabController. Je pense que ce changement affecte quand viewWillAppear est appelé.

Ce problème peut être résoluble si nous utilisons -[UIViewController addChildViewController:].

5voto

whalec Points 53

Les réponses ci-dessus un peu incomplète. Nous allons présumer que vous avez 2 contrôleurs de vue, ControllerA, et ControllerB.

ControllerA.la vue est déjà ajouté à la fenêtre(c'est le parent), et que vous souhaitez ajouter ControllerB.vue comme une sous-vue de ControllerA.

Si vous n'ajoutez pas ControllerB comme un enfant de ControllerA tout d'abord, le automaticallyForwardAppearanceAndrotationmethodstochildviewcontrollers sera ignorée, et vous serez toujours appelé par iOS5, ce qui signifie que vous pourrez appeler votre point de vue contrôleur de rappels à deux reprises.

Exemple dans ControllerA:

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
    return NO;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil];

    [self.view addSubview:self.controllerB.view];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.controllerB viewWillAppear:animated];
}

Dans ControllerB NSLogging dans viewWillAppear:

- (void)viewWillAppear:(BOOL)animated
{
    NSLog("@ControllerB will appear");
}

Cela se traduira dans iOS5 ne montrer que NSLog message deux fois. c'est à dire que Vous êtes automaticallyForwardAppearanceAndrotationmethodstochildviewcontrollers a été ignorée.

Afin de résoudre ce problème, vous devez ajouter controllerB comme un enfant de contrôleur de un.

De retour dans ControllerA de la classe:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil];
    if ([self respondsToSelector:@selector(addChildViewController:)])
        [self addChildViewController:self.controllerB];

    [self.view addSubview:self.controllerB.view];
}

Cela fonctionne maintenant comme prévu dans les deux iOS4 et iOS5 sans recourir à l'horrible hack de la vérification de la version iOS chaînes, mais plutôt de vérifier si la fonction nous sommes après est disponible.

Espérons que cette aide.

2voto

Alex Sfinx87 Points 140

C'est un comportement iOS5:
viewWillAppear, viewDidAppear, ... sont exécutés automatiquement après addSubView: pour iOS5.
Donc, pour iOS5, pas besoin d'exécuter manuellement ces méthodes comme besoin pour iOS <5.0.

Le correctif peut être:

 if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
...execute viewWillAppear or other
}
 

0voto

Ron Points 1610

Par cette méthode, vous savez quelle est la condition d'utilisation et de mise si elle est inférieure à 5,0 ou à une autre

[[UIDevice currentDevice] systemVersion]

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