2009-09-30 6 views
3

J'ai un UIViewController que j'utilise pour contrôler une vue "pop-up" pour afficher des images dans toute mon application. Il prend en charge l'autorotation, car il adapte automatiquement l'image pour qu'elle s'adapte correctement, quelle que soit l'orientation. Cela fonctionne parfaitement, mais seulement la première fois que j'initialise et affiche le contrôleur de vue. Quand il se ferme, je supprime le UIView de ma hiérarchie de vue et libère le contrôleur de vue - mais la prochaine fois que j'instancie et l'ajoute à ma hiérarchie de vue, il cesse de recevoir les messages -shouldAutorotateToInterfaceOrientation lorsque le téléphone est pivoté.Le contrôleur de vue n'obtient pas -shouldAutorotateToInterfaceOrientation: messages en deuxième chargement?

Voilà comment j'instancier et l'afficher:

popupVC = [[PopupVC alloc] init]; 
[popupVC viewWillAppear:NO]; 
[[[UIApplication sharedApplication] keyWindow] addSubview:popupVC.view]; 
[popupVC viewDidAppear:NO]; 

voilà comment je supprimer/relâcher une fois terminé:

[popupVC viewWillDisappear:NO]; 
[popupVC.view removeFromSuperview]; 
[popupVC viewDidDisappear:NO]; 
[popupVC release]; 
popupVC = nil; 

J'ai essayé une boucle à travers [[UIApplication sharedApplication] keyWindow] subviews pour voir si d'une certaine façon, ma vue popup n'est pas au top, mais elle l'est toujours. Et il a une adresse différente à chaque fois, donc je sais que c'est une instance différente de la classe contrôleur de vue.

Comme demandé, voici la méthode complète de loadViewPopupVC:

- (void)loadView { 

    UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; 
    myView.backgroundColor = self.overlayColor; 
    myView.autoresizesSubviews = NO; 
    myView.hidden = YES; 
    myView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
    self.view = myView; 
    [myView release]; 

    _isVisible = NO; 

    UIView *myMaskView = [[UIView alloc] initWithFrame:self.view.bounds]; 
    myMaskView.backgroundColor = [UIColor clearColor]; 
    myMaskView.clipsToBounds = YES; 
    myMaskView.hidden = YES; 
    myMaskView.autoresizesSubviews = NO; 
    myMaskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    [self.view addSubview:myMaskView]; 
    self.imageMaskView = myMaskView; 
    [myMaskView release]; 

    UIImageView *myImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 
    myImageView.center = self.view.center; 
    myImageView.hidden = NO; 
    myImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleHeight; 
    [self.imageMaskView addSubview:myImageView]; 
    self.imageView = myImageView; 
    [myImageView release]; 

    UIButton *myImageButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    myImageButton.frame = self.view.frame; 
    myImageButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleHeight; 
    [myImageButton addTarget:self action:@selector(clickImage:) forControlEvents:UIControlEventTouchUpInside]; 
    [self.imageMaskView addSubview:myImageButton]; 
    self.imageButton = myImageButton; 

    UIActivityIndicatorView *myActivityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    myActivityView.hidden = YES; 
    [self.view addSubview:myActivityView]; 
    myActivityView.center = self.view.center; 
    self.activityView = myActivityView; 
    [myActivityView release]; 
} 
+0

Quand configurez-vous le contrôleur de vue? En outre, je ne crois pas que vous devez appeler 'viewWillAppear:' explicitement, sauf si le but est d'empêcher l'animation. –

+0

Je l'ai mis en place dans une méthode 'UITableViewDelegate', lorsque l'utilisateur sélectionne une image à afficher. Ma méthode 'PopupVC -loadView' configure la vue et les sous-vues qu'elle utilise. J'ai pris l'habitude d'appeler explicitement '-viewWillAppear:' après avoir constaté que mon 'UITabBarController' ne fonctionnait pas correctement à moins que vous ne leur envoyiez le message ... juste une habitude je suppose. – pix0r

+0

vous ne devriez pas appeler les méthodes viewWillAppear/viewDidAppear vous-même. Je pense que vous devez repenser comment vous initialisez et nettoyez votre popup VC. –

Répondre

6

Le gestionnaire shouldAutorotateToInterfaceOrientation est pas le lieu pour un code personnalisé pour répondre aux événements de rotation. Son but est simplement de dire au système d'exploitation que votre contrôleur de vue peut pivoter. Si vous voulez avoir un code personnalisé pour gérer les événements de rotation, vous devez overide - didRotateFromInterfaceOrientation ou l'une des autres méthodes de rappel similaires en fonction de vos besoins:

  • willRotateToInterfaceOrientation:duration:
  • willAnimateRotationToInterfaceOrientation:duration:
  • didRotateFromInterfaceOrientation:
  • willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
  • didAnimateFirstHalfOfRotationToInterfaceOrientation:
  • willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:

Voir Autorotating Views dans les documents du développeur.

+0

Bon point - bien que je ne réponde pas à l'événement ici, je le corrige dans le mauvais sens. Merci d'avoir fait remarquer cela. – pix0r

+0

Bien que maintenant que je regarde j'ai un peu de code de débogage dans '-didRotateFromInterfaceOrientation:' et il n'est pas déclenché non plus. – pix0r

+0

Comment faire pour que votre contrôleur de vue écrase 'canBecomeFirstResponder' pour retourner YES, fait' [self becomeFirstResponder] 'dans' viewDidAppear: animated' et un '[self resignFirstResponder]' correspondant dans 'viewWillDisappear: animated'. Cela fait-il une différence? –

6

Je pense que cela pourrait être un bug dans le nouveau système d'exploitation 3.0. Une solution de contournement à cela serait d'utiliser NSNotificationCenter après avoir activé beginGeneratingDeviceOrientationNotifications.

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; 
} 

-(void) receivedRotate: (NSNotification *) notification { 
    DebugLog(@"ORIENTATION CHANGE"); 

    UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation]; 

     if(interfaceOrientation == UIDeviceOrientationPortrait) { 
      self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0)); 
      self.view.bounds = CGRectMake(0, 0, 320, 480); 
     } 
     else if(interfaceOrientation == UIDeviceOrientationLandscapeLeft) { 
      self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90)); 
      self.view.bounds = CGRectMake(0, 0, 480, 320); 
     } 
     else if(interfaceOrientation == UIDeviceOrientationLandscapeRight) { 
      self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90)); 
      self.view.bounds = CGRectMake(0, 0, 480, 320); 
     } 
} 
+0

'#define degreesToRadians (x) (M_PI * (x)/180.0)' – Barry

0

Mon problème est que je reçois l'événement de rotation pour mon RootViewController, mais dès que je lance mon deuxième viewController, il ne sera pas tous les signaux sauf mouvement (agitation) et le toucher. Est-ce le même problème que le message original - il est certainement similaire?

Je ai suivi avec la recommandation ci-dessus et je n'ai pas le sélecteur codé correctement donc il jette une exception dès que je tente de faire pivoter. Pendant ce temps, j'ai trouvé cette autre discussion sur le web qui confirme que le problème a été introduit en 3.0. link text

Questions connexes