Как уволить PopoverAnimated на iPad с помощью UIPopoverController в MKMapView (SDK3.2)

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

- (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, и всплывающее окно исчезнет ... но мне нужно, чтобы пользователь щелкнул кнопку в представлении, если они что-то меняют. УРГ!

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

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

Что ж, вот проблема: по определению того, как работает popoverController, вы нажимаете внутри представления отображаемого всплывающего окна (чтобы щелкнуть кнопку), но должны вызвать метод dismissPopoverAnimated: контроллера, который < strong> запустил это всплывающее окно, в моем случае 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, которые я изучаю).

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


person Jann    schedule 14.04.2010    source источник


Ответы (2)


У меня была такая же проблема ... У меня была аккуратная кнопка «закрыть» (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];
}
[...]

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

person Paul Peelen    schedule 09.05.2010
comment
Как бы я ни ненавидел это: if (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPad), потому что вы не можете использовать его в универсальном приложении или в приложении до 3.2, я отмечу это как ответ, потому что это: [detailController setPopover: aPopover] ; это то, что мне нужно. Спасибо - person Jann; 10.05.2010
comment
Да, я согласен. Учитывая мое расписание, у меня не было особого выбора, но в будущем я его поменяю. Рад, что смог помочь! С уважением, Пол - person Paul Peelen; 11.05.2010
comment
@Jann, потому что вы не можете использовать его в универсальном приложении или в приложении до 3.2. Да, ты можешь. Если у вас базовый SDK версии 3.2, он будет работать правильно при развертывании на устройствах до версии 3.2. - person user102008; 12.03.2011
comment
спасибо ... это действительно помогло мне и было именно то, что мне было нужно :) - person Azeem Shaikh; 30.05.2012
comment
Очень полезно. Это должен быть способ закрыть всплывающее окно в собственном контроллере представления. Я использую его, чтобы реализовать закрытие всплывающего окна, нажав кнопку панели навигации в всплывающем окне. - person newguy; 01.03.2013

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

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

  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;
person alones    schedule 18.09.2014