2010-06-09 13 views
9

Dans mon application, j'ai 3 UIPopOvers. Ils apparaissent lorsque l'utilisateur appuie sur les boutons de la barre d'outils. J'ai besoin de faire apparaître les popups au bon endroit quand l'utilisateur tourne l'iPad si le popover est déjà ouvert (comme le -willAnimateRotationToInterfaceOrientation :).UIPopOver et changement d'orientation

Comment puis-je le faire?

Merci d'avance!

Répondre

6

La seule solution que je l'ai trouvé à ce jour est tout simplement la fermeture du popover lorsque le dispositif est mis en rotation/

+0

Malheureusement, je ne peux rien obtenir pour déclencher la méthode willRotate de mon contrôleur de vue, où je rejeterais normalement le popover. J'aurais pensé que ça s'appellerait n'importe quoi. –

+0

Je pense aussi à cette solution que je n'arrive pas à faire. :( –

3

Si vous utilisez simplement la méthode presentPopoverFromBarButtonItem pour présenter votre popover alors le popover se déplace automatiquement à la position correcte pour la nouvelle position du bouton lorsque l'appareil est tourné.

4

Voici un fragment de code d'un de mes projets. Fondamentalement, si le popover est en cours d'affichage, vous présenter à nouveau le popover dans la méthode didRotateFromInterfaceOrientation:, qui est envoyé au contrôleur de vue après la rotation de l'interface utilisateur a eu lieu. (Les willRotate... et willAnimateRotation... méthodes sont appelées avant la rotation a eu lieu, il est au mauvais endroit pour l'appel de méthode presentPopover....)

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    // if the popover is showing, adjust its position after the re-orientation by presenting it again: 
    if (self.myPopoverController != nil) // if the popover is showing (replace with your own test if you wish) 
    { 
    [self.myPopoverController presentPopoverFromRect:attachmentRect 
               inView:myView 
          permittedArrowDirections:UIPopoverArrowDirectionUp 
              animated:YES]; 
    }  
} 

Dans ce qui précède, self.myPopoverController est une propriété de mon contrôleur de vue où Je stocke une référence à la popover quand elle est créée. Quand je rejette et rejette le popover dans des circonstances normales, je prends soin de mettre cette propriété à nil, donc je peux le vérifier pour 'non nil' pour déterminer si le survol est montré ou non.

Notez toutefois que vous n'avez pas besoin d'ignorer le popover avant la rotation. Présentez simplement le même popover à nouveau. (C'est là maintenant une référence au popover est très pratique.)

Dans votre cas, où le popover émane d'un bouton de la barre d'outils, vous pouvez utiliser quelque chose comme ce qui suit à la place:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    // if the popover is showing, adjust its position after the re-orientation by presenting it again: 
    if (self.myPopoverController != nil) // if the popover is showing (replace with your own test if you wish) 
    { 
    [self.myPopoverController presentPopoverFromBarButtonItem:barButtonItem 
            permittedArrowDirections:UIPopoverArrowDirectionAny 
                animated:YES]; 
    }  
} 
2

Je J'ai rencontré cette même question plusieurs fois. En général, je fais juste une méthode pour montrer la popover centrée comme ceci:

- (void) showPopoverForSize:(CGSize) size center:(CGPoint) center { 
    CGFloat width = size.width; 
    CGFloat height = size.height; 
    CGFloat x = center.x - width/2; 
    CGFloat y = center.y - height/2; 
    CGRect frame = CGRectMake(x, y, width, height); 
    popover.popoverContentSize = frame.size; 

    [popover presentPopoverFromRect:frame inView:self.view permittedArrowDirections:0 animated:YES]; 
} 

Puis didRotate je ferai:

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
    if (popover.isPopoverVisible) 
     [self showPopoverForSize:popover.popoverContentSize center:self.view.center]; 
} 

Cela mettra le popover au centre de toute orientation.

10

Dans iOS 7.0 et plus tard, il peut être fait en mettant en œuvre la méthode suivante disponible en UIPopoverControllerDelegate:

(void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView **)view

Pour popovers qui ont été présentés selon la méthode presentPopoverFromRect, le contrôleur popover appelle cette méthode lorsque les changements d'orientation de l'interface.

+0

Ceci est de loin le meilleur moyen de le faire après iOS 7. – logancautrell

+0

'CGRect frame = self.myView.frame; * rect = frame;' – logancautrell

+0

Cela a même corrigé un autre bug avec 'drawRect' qui ne s'appelle plus sur un –

1

Au début du changement d'orientation rejeter la popover, et après le changement d'orientation est terminée à nouveau et il change présente sa position sur l'écran:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
      [_popover dismissPopoverAnimated:YES]; 
     } 
    } 

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
    { 
     if (_popover) { 
      [_popover presentPopoverFromRect:frameRect 
                 inView:self.view 
            permittedArrowDirections:UIPopoverArrowDirectionUp 
                animated:YES]; 
     }  
    } 
+0

S'il vous plaît ajouter plus de détails, plutôt que de simplement coller le code. – kinshuk4

0

Exécution fonction popover:

func presentPopover() { 
    self.popoverFlag = true 
    //Presenting PopOver code goes here 
    // ... 
} 

Rejetant popover présenté sur changement d'orientation:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 

     if self.isKindOfClass(ViewController) && self.popoverFlag{ 
      guard self.presentedViewController != nil else { return } 
      dispatch_async(dispatch_get_main_queue()) { 
       self.presentedViewController!.dismissViewControllerAnimated(true, completion: nil) 
      } 
     } 
    } 

Présentation à nouveau popover:

func popoverPresentationController(popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>, inView view: AutoreleasingUnsafeMutablePointer<UIView?>) { 
    self.presentPopover() 
}