2010-04-14 17 views
9

Tengo un MKMapView (también un UIPopoverControllerDelegate) con Anotaciones. Este MapView tiene, en el archivo MKTestMapView.h, un UIPopoverController* popoverController definido en la interfaz @ y un @property (nonatomic, retain) UIPopoverController* popoverController; definido fuera de la sección @interface. Este controlador es @synthesized en el archivo MKTestMapView.m y se publica en la sección - (void)dealloc. Las anotaciones en este MapView tienen rightCalloutAccessoryView s definidas a lo siguiente:Cómo descartar el PozoAnimado en iPad con UIPopoverController en MKMapView (SDK3.2)

- (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]; 


... 

} 

Ahora aquí viene la parte divertida. En primer lugar, no estoy seguro si necesito que maximumLabelSize y rect sean del mismo tamaño. Soy nuevo en el controlador de popover así que estoy jugando esto de oído ...

Bien, el popover muestra. Ahora a descartarlo. Puedo hacer clic en cualquier lugar en mapView2 y el popover se va ... pero necesito que el usuario haga clic en un botón en la vista si cambian algo. ¡URGH!

Los documentos muestran:

despedir a un popover mediante programación, llamada la dismissPopoverAnimated: método del controlador popover.

Bueno, aquí está el problema: Por definición de cómo funciona el popoverController, que hace clic dentro la vista de la popover mostrado (hacer clic en el botón), pero tienen que activar el método del controlador dismissPopoverAnimated: que lanzó esta vista de popover, en mi caso, popoverController dentro del archivo MKTestMapView.m.

Ahora, habiendo dicho todo esto, recordemos, [popoverController release] no sucede hasta que:

- (void)dealloc { 
[popoverController release]; 
[mapView release]; 
    [super dealloc]; 
} 

Por lo tanto, me acaba de hacer lo siguiente dentro del botón (desordenado pero puede funcionar):

(suponiendo mi punto de vista es un popover TableView) En el:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
MKTestMapView * mKTestMapView = [[MKTestMapView alloc] init]; 
[[mKTestMapView popoverController].dismissPopoverAnimated:YES]; 
} 

Aquí está mi problema: no puedo averiguar si hacer lo anterior me da una reference (si no es tal una cosa) a la vista existente que está en la pantalla y, por lo tanto, a la vista que es el propietario de ese popoverController. Si es tan simple como

[[[self parentView] popoverController].dismissPopoverAnimated:YES]; 

voy a pegarme un tiro porque yo no creo que es la sintaxis correcta, ya sea!

Esto debería ser fácil ... pero estoy perdido. (Probablemente frustrado con tantas diferencias de iPad que estoy aprendiendo).

¿Alguien puede explicar más?

Respuesta

18

Tuve el mismo problema ... Tenía un pulcro botón de "cerrar" (X) en la parte superior de mi vista cargado por el popover, pero no funcionó. En mi aplicación universal, se presentará como una nueva vista, para que el código permanezca.

Lo que hice fue ahora que he añadido lo siguiente a mi detailedPinView (la opinión de las cargas popover):

en el archivo detailedPinView.h:

@interface detailedPinView : UIViewController { 
    [...] 
    UIPopoverController *popover; 
    [...] 
} 

-(void)setPopover:(UIPopoverController*)aPopover; 

En el archivo detailedPinView.m:

- (void)setPopover:(UIPopoverController*)aPopover 
{ 
    popover = aPopover; 
} 

el botón X cierra la vista usando un IBAction, esto es lo que hice allí:

En el archivo 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]; 
    } 
} 

En la carga de clases del mi mapa y la vista popover I añade el siguiente código:

[...] 
-(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]; 
} 
[...] 

No sé si el era la respuesta que estaban esperando, creo que podría ser una manera un poco desordenada de hacerlo ... pero dar el horario de trabajo funcionó como un encanto :)

+0

Por mucho que me gusta este: si (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) porque no puede usarlo en una aplicación universal o en una aplicación anterior a la 3.2, voy a marcar esto como la respuesta porque esto: [detailController setPopover: aPopover]; es lo que necesitaba Thx – Jann

+1

Sí, estoy de acuerdo. No tuve mucha elección dado mi horario, pero lo cambiaré "en el futuro". ¡Me alegro de poder ayudar! Saludos, Paul –

+1

@Jann "porque no puede usarlo en una aplicación universal o en una aplicación anterior a la 3.2". Sí tu puedes. Siempre que su SDK base sea 3.2, se ejecutará correctamente cuando se implemente en dispositivos pre-3.2. – user102008

1

Aquí hay otra solución simple.

Descubrí que debemos seguir los siguientes pasos para descartar claramente los popovers.

  1. expulsar a un popover.
  2. libera una vista cargada por el popover.

Antes de iOS8, casi todos nosotros podemos lanzar primero una vista cargada por un popover, y luego descartamos programáticamente el popover. Sin embargo, en iOS8, realizamos los pasos en reversa.

Antes iOS8, mi código de despedir a un 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 
} 

En iOS8, la parte de código Dismissing debe cambiarse como abajo,

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; 
Cuestiones relacionadas