web-dev-qa-db-fra.com

Les popovers ne peuvent pas être présentés à partir d'une vue sans fenêtre

Qu'est-ce que cette erreur indique:

 "Les popovers ne peuvent pas être présentés depuis une vue sans fenêtre." 
53
a111

la vue à laquelle vous ajoutez le popover doit déjà avoir été ajoutée à une fenêtre avec la méthode "addSubview:".

Essayez d'attendre jusqu'à

- (void) didMoveToWindow

est appelé pour la vue, puis charge le popover

24
hey68you

la chose qui m'a sauvé la vie:

if (self.view.window != nil)
    [popoverController presentPopoverFromRect:CGRectMake(44, yCoord, 111, 111) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

en ajoutant si condition cela ne plante plus. Je ne comprends pas vraiment parce que la fonction presentPopoverFromRect est TOUJOURS appelée. Il n'y a pas de situation où la fenêtre serait nulle, mais de toute façon cela a fait l'affaire. 

edit: J'ai ce code dans viewDidAppear. Néanmoins, dans la plupart des cas, il suffit de passer de presentPopoverFromRect à viewDidAppear ou didMoveToWindow mais dans mon cas, la condition si était nécessaire. 

30
Maciek z Wrocławia

J'ai ce problème. 

J'avais une UITabBarController comme vue détaillée et j'ai défini barButtonItem comme étant leftBarButtonItem sur les trois contrôleurs de navigation de la barre d'onglets. 

vcChart.navigationItem.leftBarButtonItem = barButtonItem;
vcAnalysis.navigationItem.leftBarButtonItem = barButtonItem;
vcTechnicals.navigationItem.leftBarButtonItem = barButtonItem;

Il s'avère que seul le dernier ajouté est valide et les deux précédents renvoient l'exception lorsque vous appuyez dessus.

Pour résoudre ce problème, j'ai uniquement défini le paramètre leftBarButtonItem pour le contrôleur de vue visible, et je viens de faire basculer barButtonItem sur le contrôleur de vue visible chaque fois que l'utilisateur bascule.

4
Lewis Anderson

Vient de rencontrer ce problème. Il s'est avéré que le paramètre inView: utilisait un IBOutlet qui n'était pas connecté à IB. Ainsi, une tentative a été faite pour lancer le popover in néant. Ça ne marche pas.

Assurez-vous donc que vous utilisez une vue valide.

2
user161814

Il y a plusieurs façons d'obtenir cette erreur. En gros, vous devez attendre pour appeler la commande presentPopover jusqu'à ce que votre vue d'appel soit ajoutée à une fenêtre. Je l'ai fait de cette façon. 

- (void)viewDidAppear:(BOOL)animated
{
    [self methodThatDisplaysPopOver];
}

Mon appel presentPopoverFromRect se trouve dans ma fonction methodThatDisplaysPopOver.

Vous pouvez protéger chaque appel presentPopover comme le suggère MobiMaciek avec cela. 

if (self.view.window != nil)
    [popoverController presentPopoverFromRect:CGRectMake(10, 10, 100, 100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

Cependant, je pense qu'il serait préférable de comprendre quand self.view.window est assigné et assurez-vous que vous vous présentez une fois que la vue a une fenêtre. 

2
Joshua Dance

J'ai reçu le même message d'erreur lors de l'attribution de la même variable UIBarButtonItem à plusieurs éléments de navigation que Lewis. Mon exemple était légèrement plus compliqué car j'utilisais une UISplitViewController

Dans ma RootViewController, j'ai un tableau de tableaux pour accomplir plusieurs sections dans ma table. Chaque fois que l'utilisateur clique sur une ligne de la table, un nouveau contrôleur de vue "Détail" est placé dans le volet de droite de mon splitViewController. Avant de définir le leftBarButtonItem = nil, je recevrais une erreur de segmentation après 3-4 clics du bouton "Menu" avec la même erreur que a111. J'ai mis à jour mon code pour récupérer le contrôleur de vue de détail précédent et définir l'élément leftBarButtonItem sur nil.

allData est mon NSMutableArray qui contient plusieurs autres NSMutableArrays en tant qu’objets. 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Retrieve the new detail view controller
    UIViewController *detailViewController = [[self.allData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];

    // Add the detail view controller to a navigation controller and set the bar style
    UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
    detailNavigationController.navigationBar.barStyle = [[NSUserDefaults standardUserDefaults] integerForKey:@"UIBarStyle"];

    // Retrieve previous detail view controller and remove the leftBarButtonItem
    UINavigationController *previousDetailNavigationController = [splitViewController.viewControllers objectAtIndex:1];
    UIViewController *previousDetailViewController = [[previousDetailNavigationController viewControllers] lastObject];
    previousDetailViewController.navigationItem.leftBarButtonItem = nil;

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailNavigationController, nil];
    splitViewController.viewControllers = viewControllers;

    [detailNavigationController release];
    [viewControllers release];

    // Dismiss the popover if it's present.
    if (popoverController != nil) {
        [popoverController dismissPopoverAnimated:YES];
    }

    // This sets the left bar to nil when in landscape and equal to "Menu" when in portrait.
    // We need to remove rootPopoverButtonItem from the previous viewController...
    detailViewController.navigationItem.leftBarButtonItem = rootPopoverButtonItem;
} 

Le message d'erreur était un peu décevant au début, mais les réponses ci-dessus m'ont aidé. Je me demande pourquoi je pourrais cliquer sur le bouton "Menu" jusqu'à 3-4 fois avant le segfault ... J'examinerai davantage.

1
TPoschel

Cette erreur s'est également produite lorsque le paramètre inView: Parameter est incorrect - pour tester, essayez self.view.

1
John Goodstadt

oui, vous avez raison, mais nous pouvons néanmoins y ajouter une sous-vue de la classe parente. il peut donc être représenté depuis une vue qui a une fenêtre:

[popoverController.contentViewController.view addSubview:mySubView];
1
Steve

j'ai eu le même problème, après avoir ajouté PresentPopOver in viewDidAppear cela a été résolu

- (void) viewDidAppear:(BOOL)animated{
     CGRect popoverRect = screenBounds;         
     popoverRect.size.width = MIN(popoverRect.size.width,0) ;
     popoverRect.Origin.x  = screenBounds.Origin.x;

     [popoverController
     presentPopoverFromRect:popoverRect
     inView:self.view
     permittedArrowDirections:UIPopoverArrowDirectionAny
     animated:YES];
}

cela se passait comme inView: self.view devrait être appelé après viewDidLoad comme suggéré par @ hey68You et MobiMaciek ..

0
iMeMyself

J'ai eu un problème comme ça. A reçu ce message en cliquant sur un élément UIBarButton personnalisé qui a appelé une méthode de sélecteur avec did performSeque.

Le problème était que ma suite était toujours attachée à l’item UIBarButton. Il aurait dû être attaché à la vue principale du contrôleur de vue. Cela a changé et a bien fonctionné.

P.S., tout cela a commencé parce que je voulais ajouter un bouton "info" à ma UIToolBar. Ce n'est pas un dans la liste fournie par le système et devrait être.

0
caprijoe

Il y aura une vue à partir de laquelle vous demanderez d’afficher votre popover. La raison de cette erreur est que vous n’avez pas créé cette vue en tant que sous-vue de la fenêtre.

 [self.view addSubview:displayPopOverVC];

où displayPopOverVC est le contrôleur de vue à partir duquel popOver apparaît

0
SumiSadiq

J'avais le même message d'erreur que l'OP, dans une situation très similaire à celle signalée par TPoschel, sauf que j'avais un contrôleur de vue fractionnée avec un contrôleur de barre d'onglets intégré dans le volet de détail et un contrôleur de navigation à l'intérieur. L'élément de bouton de barre est ajouté à la barre de navigation leftBarButtonItem.

Sur iOS5.0 uniquement (et non sur la version 5.1), il semble que vous deviez invalider l’élément de bouton de barre de la barre d’onglet que vous quittez en le réglant sur nil. Avant d’ajouter le bouton de la barre à la barre de navigation de l’onglet que vous allez consulter. 

Si je ne le fais pas, à partir du débogage de mon propre code, la propriété window de l'élément de bouton de barre reste définie sur nil et provoque l'exception, sur en retournant à un écran où vous étiez auparavant. J'imagine que l'effet secondaire de la définition de l'objet leftBarButtonItem dans l'élément de navigation est désactivé et définit le cadre. Mais cela ne semble pas déranger à moins que le bouton ne soit différent de ce qui est actuellement défini. D'où la nécessité de le régler à zéro lorsque vous quittez un onglet, même s'il s'agit techniquement du même bouton que celui qui est passé.

Je voterais contre la réponse de TPoschel, sauf que SO ne me le permettra pas.

0
Rob Glassey

J'ai remplacé 

[actionSheet showFromBarButtonItem:self.navigationController.navigationItem.leftBarButtonItem animated:YES];

avec

[actionSheet showInView:self.view];
0
Rose Perrone