web-dev-qa-db-fra.com

UIPopoverController redimensionnant automatiquement à la hauteur maximale sur pushViewController

J'ai un popover contenant un UINavigationController. Je peux afficher le popover bien, et il contient le navController très bien. NavController contient une tableView et lorsque je sélectionne un élément, il crée une nouvelle vue de détail:

     DeviceDetailViewController *detailViewController = 
[[[DeviceDetailViewController alloc] initWithNibName:@"DeviceDetailViewController" bundle:nil] autorelease];

Je pousse ensuite le nouveau contrôleur de vue:

    [self.navigationController pushViewController:detailViewController animated:YES];

C'est à ce moment que le problème survient: _ ​​après en poussant la nouvelle vue, la fenêtre popover est redimensionnée à la hauteur maximale disponible sur l'iPad.

J'ai essayé de régler la hauteur de toutes les vues dans xib à une hauteur fixe plutôt que flexible. J'ai essayé explicitement de régler la hauteur du popover. J'ai également essayé d'utiliser différents contrôleurs de vue en tant que vue enfant. Le problème persiste: le popover veut que se redimensionne automatiquement à la hauteur maximale chaque fois qu'une nouvelle vue est transmise au contrôleur de navigation.

Voici une question qui traite de l’essai de contrôler délibérément la taille du popover lorsqu’on affiche de nouvelles vues:

Je pensais que cela pourrait être une méthode de force brute pour contrôler la taille. Chose étrange, cependant, cela provoque en réalité quelques problèmes graphiques rapides (comme si la vue était fraîchement animée), suivis de la poursuite du redimensionnement comme décrit ci-dessus.

En d'autres termes, quelque chose force littéralement le popover à atteindre sa hauteur maximale et semble se produire après toutes les méthodes de délégation ont été appelées.

Est-ce le contrôleur de navigation? Quelqu'un a-t-il vu ce genre de chose?

68
SG1

Cela a résolu le problème après avoir eu le même problème (aujourd'hui également):

EDIT: Comme contentSizeForViewInPopover est obsolète en iOS7.0, utilisez donc preferredContentSize.

Réponse originale ci-dessous :

Dans votre detailViewController, ajoutez ceci:

- (void)viewWillAppear:(BOOL)animated {

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

    [super viewWillAppear:animated];

}

Vous souhaitez également ajouter quelque chose de similaire à votre DeviceDetailViewController d'origine pour éviter tout redimensionnement lorsque vous appuyez sur le NavbarItem précédent.

123
borked

Tout comme le fait de le manipuler dans viewWillAppear, une autre façon de procéder consiste à remplacer contentSizeForViewInPopover. Très laconique:

-(CGSize)contentSizeForViewInPopover
{
    return self.view.bounds.size;
}
30
Peter DeWeese

Pour IOS5

Je vous recommande de le faire dans:

- (void)viewDidLoad {
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

}
30
MUH Mobile Inc.

J'ai eu un problème similaire.

J'ai eu un popover présent à partir d'un bouton dans une barre d'outils. Le popover a été défini à une taille spécifique. C'était une vue de table. Lorsque la ligne de la table a été sélectionnée, un nouveau contrôleur de vue avec un contrôleur de navigation a été appelé.

Lorsque le bouton Précédent était sélectionné, le popover devenait la taille par défaut (320x1100 je crois), au lieu de la taille spécifique que je désirais.

Le code original était:

  MyTableViewController *myVC = [[MyTableViewController alloc] init];
  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  [myVC release];
  [navController release];
  [popover release];

J'ai ajouté une ligne pour résoudre le problème. J'admets que c'est un peu une solution de contournement, car je devais soustraire la hauteur de l'en-tête. Peut-être que l'un de vous pourrait m'éclairer avec une meilleure méthode. En tout cas, ça marche.

  MyTableViewController *myVC = [[MyTableViewController alloc] init];

  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  //Subtract the height of the header to match the total popover size (not just the view).
  myVC.contentSizeForViewInPopover = CGSizeMake(400.0, 500-44);

  [myVC release];
  [navController release];
  [popover release];

Je crois que lorsqu'un contrôleur de navigation est impliqué et que le bouton Précédent est enfoncé, la taille par défaut du popover est rétablie. En ajoutant la propriété contentSizeForViewInPopover pour le contrôleur de vue myVC, la taille spécifique est forcée.

J'espère que c'est utile.

Kurt

11
Kurt

Pour iOS 7, utilisez les éléments suivants:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 768); // size of view in popover
    self.preferredContentSize = size;
}

UIViewController.contentSizeForViewInPopover est déconseillé pour la première fois dans iOS 7.

9
Abdullah Umer

En réponse à des problèmes graphiques avec des animations:

Les animations UIPopoverController sont en conflit avec les animations des contrôleurs UINavigation si vous créez le popover avec un contrôleur UINavigation à l'intérieur. Il en résulte des problèmes graphiques lors de l'animation. Pour résoudre le problème, définissez le paramètre animé sur false lorsque vous appuyez sur d'autres contrôleurs ou lorsque vous affichez la barre d'outils.

En poussant les contrôleurs de vue:

[self.navigationController pushViewController:detailViewController animated:NO];

Rendre la barre d’outils visible: 

[[self navigationController] setToolbarHidden:NO animated:NO]; 

Si vous définissez l'animation: NON, les animations auront l'air correctes dans un UIPopoverController.

6
Paul Solt

Pourquoi ne pas simplement définir la contentSizeForViewInPopover avant de placer le prochain contrôleur dans la pile de navigation? Pas besoin de définir des tailles dans viewWillAppear et autres.

[nextController setContentSizeForViewInPopover:[self contentSizeForViewInPopover]];
[[self navigationController] pushViewController:nextController animated:YES];

Fonctionne sur IOS 5.1

5
MrJre

Légère variante du conseil de borked (qui m'a orienté dans la bonne direction, merci pour cela!), Voici ce que je fais lorsque j'applique un nouveau contrôleur pour conserver la taille avant de le pousser:

productViewController.contentSizeForViewInPopover = self.view.bounds.size;
self.contentSizeForViewInPopover = self.view.bounds.size;

[self.navigationController pushViewController:productViewController animated:YES];

J'aime cela parce que je n'ai pas à coder en dur les valeurs de popover dans tous les contrôleurs de vue (bon car je les utilise à différentes hauteurs).

La ligne self.contentSizeForViewInPopover permet de conserver la taille lorsque l'utilisateur appuie sur back . Je suppose que vous pourriez mettre cette ligne ailleurs, comme viewWillAppear ou où bon vous semble.

Semble travailler ...

4
William Denniss

Dans le - (void) viewDidLoad de tous les contrôleurs de vue que vous utilisez dans la navigation, écrivez le code:

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
2
SumiSadiq

Il existe deux façons de définir le contentSizeForViewInPopover dans le storyboard. Vous pouvez définir vos contrôleurs de vues associés à votre contrôleur de navigation sur FreeForm et définir les vues racine à la taille souhaitée. Ou bien, vous pouvez conserver la métrique simulée comme induite, cochez la case "Utiliser la taille explicite" et définissez la taille souhaitée.

Ensuite, dans chaque contrôleur de vue qui se trouve dans votre contrôleur de navigation, ajoutez ce qui suit ...

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

     ["yourpopoverController" setPopoverContentSize:CGSizeMake(self.
           contentSizeForViewInPopover.width, seld.contentSizeForViewInPopover.height + self.
           navigationController.navigationBar.frame.size.height) animated:YES];
}

Dans l'animation de transition, la nouvelle vue s'alignera sur le haut, puis la hauteur sera ajustée en conséquence.

Ainsi, vous n'avez pas besoin de remplacer contentSizeForViewInPopover, ni de spécifier une autre taille spécifiquement dans vos contrôleurs de vue. Tout est dans le storyboard.

Si l'un de vos contrôleurs de vue a une hauteur variable, vous devez redéfinir contentSizeForViewInPopover dans cette vue comme suit ...

- (CGSize)contentSizeForViewInPopover {
    return CGSizeMake(450, "calculate your height here");
}
2
Matt Becker

Ce truc peut avoir fonctionné une fois, mais pas avec xCode 6 où contentSizeForViewInPopover est obsolète. Heureusement, il est respecté au moment du chargement du storyboard. J'ai téléchargé un éditeur XML (Xmplify) et piraté le storyboard. Définissez la clé contentSizeForViewInPopover à la taille souhaitée. Enregistrez et remplacez (faites une copie d’abord) le storyboard.

Plus précisement : 

< viewController>

     <value key="contentSizeForViewInPopover" type="size" width="450" height="280" / >

</viewController>
1
Joe313

Ne travaille pas pour moi quand j'utilise ceci:

[UIPopoverController 
    [UINavigationController] = root vc = [UIViewController vc1] => [UIViewController vc2] 
]

Lorsque l’apparence popover est bonne, appuyez sur le bouton sur vc1 et poussez vc2 sur le contrôleur de navigation.

Revenez ensuite à vc1 (racine) en appuyant sur le bouton dans vc2 (méthode popToRootViewController);

Nous pouvons voir que la taille de la popover change, mais la taille de vc1 est ancienne ... QU'EST IS CE ???

Ok, maintenant travaille ... Ajouter une propriété popover dans mon contrôleur

self.contentSizeForViewInPopover = (CGSize){400, 200};
self.navigationController.contentSizeForViewInPopover = self.contentSizeForViewInPopover;
self.popover.popoverContentSize = self.contentSizeForViewInPopover;
0
iTux

Sous Swift 4 et iOS 11, la seule solution possible était pour moi. Pour utiliser showViewController:sender: and showDetailViewController:sender: au lieu de presentViewController:animated:completion:

De la doc Apple 

Les méthodes showViewController: sender: et showDetailViewController: sender: offrent le moyen le plus adaptatif et le plus flexible d’afficher des contrôleurs de vue. Ces méthodes permettent au contrôleur de la vue présentation de décider de la meilleure façon de gérer la présentation. Par exemple, un contrôleur de vue de conteneur peut incorporer le contrôleur de vue en tant qu'enfant au lieu de le présenter de manière modale. Le comportement par défaut présente le contrôleur de vue sous forme modale.

0
BilalReffas