Come dismissPopoverAnimated su iPad con UIPopoverController a MKMapView (SDK3.2)
-
26-09-2019 - |
Domanda
Ho un MKMapView (anche UIPopoverControllerDelegate) con annotazioni. Questo MapView ha, nel file MKTestMapView.h , un UIPopoverController* popoverController
definito nel @interface e un @property (nonatomic, retain) UIPopoverController* popoverController;
al di fuori della sezione @interface
definito. Questo controller è @synthesized
nel file MKTestMapView.m ed è rilasciato nella sezione - (void)dealloc
. Le annotazioni in questo MapView hanno rightCalloutAccessoryView
s definito al seguente:
- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)aview calloutAccessoryControlTapped:(UIControl *)control{
...
CGPoint leftTopPoint = [mapView2 convertCoordinate:aview.annotation.coordinate toPointToView:mapView2];
int boxDY=leftTopPoint.y;
int boxDX=leftTopPoint.x;
NSLog(@"\nDX:%d,DY:%d\n",boxDX,boxDY);
popoverController = [[UIPopoverController alloc] initWithContentViewController:controller];
popoverController.delegate = self;
CGSize maximumLabelSize = CGSizeMake(320.0f,600.0f);
popoverController.popoverContentSize = maximumLabelSize;
CGRect rect = CGRectMake(boxDX, boxDY, 320.0f, 600.0f);
[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
...
}
Ora qui viene il bello. Prima di tutto, non sono sicuro se ho bisogno maximumLabelSize
e il rect
per avere la stessa dimensione. Sono nuovo al popovercontroller così sto giocando questo orecchio ..
D'accordo, gli spettacoli popover. Ora a che respinge. Posso cliccare in qualsiasi punto mapView2 e la popover va via ... ma ho bisogno l'utente a cliccare su un pulsante nella vista se cambiano nulla. URGH!
La documentazione mostrano:
Per chiudere un popover di programmazione, chiamare il dismissPopoverAnimated: metodo del controller popover.
Bene, qui è il problema: Per definizione di come funziona il popoverController, si fa clic su all'interno la vista del popover visualizzato (fare clic sul pulsante), ma hanno per far scattare il metodo dismissPopoverAnimated:
del controller che lanciato questo punto di vista popover, nel mio caso, il popoverController
all'interno del file MKTestMapView.m .
Ora, dopo aver detto tutto ciò che, ricordiamo, [popoverController release]
non accade fino a quando:
- (void)dealloc {
[popoverController release];
[mapView release];
[super dealloc];
}
Quindi, io faccio solo il seguente all'interno del pulsante (disordinato, ma può funzionare):
(Supponendo mio punto di vista è un popover TableView) In:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MKTestMapView * mKTestMapView = [[MKTestMapView alloc] init];
[[mKTestMapView popoverController].dismissPopoverAnimated:YES];
}
Ecco il mio problema: non riesco a capire se fare quanto sopra mi dà un reference
(se c'è una cosa del genere) per il esistente vista che è sullo schermo - e quindi la vista che è il proprietario di quel popoverController. Se è così semplice come
[[[self parentView] popoverController].dismissPopoverAnimated:YES];
I sparerà me cos non credo che sia la sintassi corretta sia!
Questo dovrebbe essere facile ... eppure sono persa. (Probabilmente solo frustrato con così tante differenze iPad che sto imparando).
Qualcuno può spiegare di più?
Soluzione
ho avuto lo stesso problema ... ho avuto un modo accurato pulsante "Chiudi" (X) nella parte superiore del mio punto di vista caricato dal popover, ma non ha funzionato. Nella mia app universale che sarà presentato come una nuova visualizzazione, in modo che il codice dovrebbe rimanere.
Quello che ho fatto oggi è stato che ho aggiunto la seguente alla mia detailedPinView (la vista dei carichi popover):
nel file detailedPinView.h:
@interface detailedPinView : UIViewController {
[...]
UIPopoverController *popover;
[...]
}
-(void)setPopover:(UIPopoverController*)aPopover;
Nel file detailedPinView.m:
- (void)setPopover:(UIPopoverController*)aPopover
{
popover = aPopover;
}
Il tasto X chiude la vista utilizzando un IBAction, questo è quello che ho fatto lì:
Nel file detailedPinView.m:
-(IBAction)releaseDetailedView:(UIButton *)sender
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
if (popover != nil)
{
[popover dismissPopoverAnimated:YES];
}
else {
NSLog(@"Nothing to dismiss");
}
}
else{
[self.parentViewController dismissModalViewControllerAnimated: YES];
}
}
Nella classe di carico la mia mappa e la vista popover ho aggiunto il seguente codice:
[...]
-(void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control
{
UIViewController *detailController = [[detailedPinView alloc] initWithNibName:@"detailedPinView"
bundle:nil
annotationView:pin];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:detailController];
[aPopover setDelegate:self];
[aPopover setPopoverContentSize:CGSizeMake(320, 320) animated:YES];
[detailController setPopover:aPopover];
[detailController release];
[mapView deselectAnnotation:pin.annotation animated:YES];
self.popoverController = aPopover;
[mapView setCenterCoordinate:pin.annotation.coordinate animated:YES];
[self.popoverController presentPopoverFromRect:CGRectMake(382,498,0,0) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
else
{
[self presentModalViewController: detailController animated:YES];
}
[detailController release];
}
[...]
Non so se la era la risposta che speravano, penso che potrebbe essere un po 'un modo disordinato per farlo ... ma dando il calendario questo ha funzionato come un fascino:)
Altri suggerimenti
Ecco un'altra soluzione semplice.
ho scoperto che dovremmo seguire la seguente procedura per respingere chiaramente popovers.
- licenziare un popover.
- rilasciare una vista caricato dal popover.
Prima di iOS 8, quasi tutti noi può rilasciare una vista caricato da un popover prima, e poi di programmazione respingere il popover. Tuttavia, in iOS 8, facciamo i passi in revers.
Prima di iOS 8, il mio codice di licenziamento di una popover
// creating a popover loading an image picker
picker = [[UIImagePickerController alloc] init];
...
pickerPopover = [[UIPopoverController alloc] initWithContentViewController:picker];
[pickerPopover presentPopoverFromRect:aFrame inView:aView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
// dismissing the popover
[picker.view removeFromSuperview]; // (1) release a view loaded by a popover
[picker release], picker = nil;
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
[pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover
}
In iOS 8, la parte di codice che respinge dovrebbe essere cambiato come sotto,
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
[pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover first
}
[picker.view removeFromSuperview]; // (1) and then release the view loaded by the popover
[picker release], picker = nil;