Как убрать PopoverAnimated на iPad с помощью UIPopoverController в MKMapView (SDK3.2) - PullRequest
9 голосов
/ 14 апреля 2010

У меня есть MKMapView (также UIPopoverControllerDelegate) с аннотациями. Этот файл MapView имеет в файле MKTestMapView.h значение UIPopoverController* popoverController, определенное в @interface, и значение @property (nonatomic, retain) UIPopoverController* popoverController;, определенное вне раздела @interface. Этот контроллер @synthesized в файле MKTestMapView.m и выпущен в разделе - (void)dealloc. Аннотации в этом MapView имеют rightCalloutAccessoryView s, определенные следующим образом:

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


...

}

Теперь вот самое интересное. Прежде всего, я не уверен, что мне нужно, чтобы maximumLabelSize и rect были одинакового размера. Я новичок в popovercontroller, поэтому я играю это на слух ..

Хорошо, поповер показывает. Теперь чтобы отклонить это. Я могу щелкнуть в любом месте на mapView2, и всплывающее окно исчезнет ... но мне нужно, чтобы пользователь щелкнул кнопку в представлении, если они что-то изменят. Urgh!

Документы показывают:

Чтобы закрыть поповер программно, вызовите dismissPopoverAnimated: метод контроллера поповера.

Ну, вот проблема: по определению того, как работает popoverController, вы нажимаете внутри представление отображаемого поповера (чтобы нажать кнопку), но должны запускать метод dismissPopoverAnimated: контроллер, который запустил это всплывающее представление, в моем случае, popoverController внутри MKTestMapView.m файла.

Теперь, сказав все это, запомните, [popoverController release] не случится до:

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

Итак, я просто делаю следующее внутри кнопки (грязно, но может работать):

(Предполагается, что мой поповерный просмотр - это TableView) В:

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

Вот моя проблема: я не могу понять, дает ли выполнение вышеизложенного мне reference (если есть такая вещь) для существующего представления, которое находится на экране - и, следовательно, посмотреть, что является владельцем этого popoverController. Если это так просто, как

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

Я застрелюсь, потому что я тоже не думаю, что это правильный синтаксис!

Это должно быть легко ... но я потерян. (вероятно, просто разочарован таким количеством различий в iPad, которые я изучаю).

Кто-нибудь может объяснить больше?

Ответы [ 2 ]

18 голосов
/ 10 мая 2010

У меня была та же проблема ... У меня была аккуратная кнопка "X" в верхней части окна, загруженная поповером, но она не работала. В моем универсальном приложении оно будет представлено как новый вид, так что код должен остаться.

Что я сделал сейчас, так это то, что я добавил следующее в мой подробный PinView (представление, которое загружает поповер):

в подробном файлеPinView.h:

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

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

В подробном файлеPinView.m:

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

Кнопка X закрывает вид с помощью IBAction, вот что я сделал там:

В подробном файлеPinView.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];
    }
}

В классе, загружающем мою карту и всплывающее окно, я добавил следующий код:

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

Я не знаю, был ли ответ, на который вы надеялись, я думаю, что это может быть немного грязный способ сделать это ... но, учитывая расписание, это сработало как шарм

1 голос
/ 18 сентября 2014

Вот еще одно простое решение.

Я обнаружил, что мы должны выполнить следующие шаги для явного отклонения поповеров.

  1. отклонить поповер.
  2. освободить представление, загруженное поповером.

До выхода iOS8 почти все из нас могут сначала выпустить представление, загруженное поповером, а затем мы программно отклоняем его. Однако в iOS8 мы делаем шаги в обратном порядке.

До iOS8 мой код отклонения поповера

// 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
}

В iOS8 часть кода отклонения должна быть изменена, как показано ниже,

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;
...