Come Ed Marty già scritto
Se si vuole licenziare un popover premendo un pulsante, un posto rilevante dovrebbe tenere un riferimento alla popover
Questo è molto vero ; tuttavia, quando mostra un UIPopoverController, la classe che apre il popovercontroller mantiene già questa risorsa. Quindi, quello che potresti fare è usare questa classe come classe delegata per il tuo controller Popover.
Per fare ciò, è possibile eseguire quanto segue, che utilizzo nel mio codice. In apertura del popover la classe, questo è il mio codice:
- (void)showInformationForView:(Booking*)booking frame:(CGRect)rect
{
BookingDetailsViewController *bookingView = [[BookingDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped booking:booking];
[bookingView setDelegate:self];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:bookingView];
self.popController = [[UIPopoverController alloc] initWithContentViewController:navController];
[self.popController setDelegate:self];
[self.popController setPopoverContentSize:CGSizeMake(320, 320)];
rect.size.width = 0;
[self.popController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
- (void)dismissPopoverAnimated:(BOOL)animated
{
[self.popController dismissPopoverAnimated:animated];
}
Quindi quello che sto facendo qui è la creazione di un UINavigationController
e l'impostazione di un BookingDetailsViewController
come rootViewController
. Quindi aggiungo anche la classe corrente come delegato a questo BookingDetailsViewController
.
La seconda cosa che ho aggiunto è un metodo di licenziamento chiamato dismissPopoverAnimated:animated
.
Nel mio BookingDetailsViewController.h
ho aggiunto il seguente codice:
[...]
@property (nonatomic, strong) id delegate;
[...]
E nella mia BookingDetailsViewController.m
ho aggiunto questo codice:
[...]
@synthesize delegate = _delegate;
- (void)viewDidLoad
{
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeView)];
[self.navigationItem setRightBarButtonItem:closeButton];
[super viewDidLoad];
}
- (void)closeView
{
if ([self.delegate respondsToSelector:@selector(dismissPopoverAnimated:)]) {
[self.delegate dismissPopoverAnimated:YES];
}
else {
NSLog(@"Cannot close the view, nu such dismiss method");
}
}
[...]
Quello che succede è che quando il pulsante "Chiudi" nella UINavigationController è premuto, viene chiamato il metodo closeView
. Questo metodo controlla se il delegato risponde a dismissPopoverAnimated:animated
e, in tal caso, lo chiama. Se non risponde a questo metodo mostrerà un messaggio di log e non farà altro (quindi non si bloccherà).
Ho scritto il mio codice usando ARC, quindi non c'è gestione della memoria.
Spero che questo ti abbia aiutato.
grazie. Cambierò il codice! – SpaceDog
Il secondo paragrafo è estremamente importante in questa risposta. Ricorda, secondo la Guida alla programmazione dell'iPad: "Ricorda però che è tua responsabilità archiviare un riferimento al controller popover in modo da poterlo eliminare." Il sistema non ne fornisce uno per impostazione predefinita. " Quindi, non fare un "rilascio" su di esso (causerà comunque un crash) finché la vista genitore non è entrata nella fase dealloc. (questo è il mio metodo di sicurezza). – Jann
usa solo [self dismissViewControllerAnimated: YES completion: nil]; "Il controller di visualizzazione che presenta è responsabile della rimozione del controller di visualizzazione presentato. Se si chiama questo metodo sul controller di visualizzazione presentato, esso inoltra automaticamente il messaggio al controller di visualizzazione che presenta." –