Подтвердить что ты не робот

Как исправить UIPopoverController является устаревшим предупреждающим сообщением?

Я использую код этого кода

mediaLibraryPopover = [[UIPopoverController alloc] 
                        initWithContentViewController:avc];
[self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds] 
                          inView:theButton 
                          permittedArrowDirections:UIPopoverArrowDirectionAny 
                          animated:YES];

И я получаю это предупреждение в Xcode-7.

UIPopoverController is deprecated ,first deprecated in iOS 9.0 - UIPopoverController is deprecated. Popovers are now implemented as UIViewController presentations. Use a modal presentation style of UIM
4b9b3361

Ответ 1

Вам больше не нужно UIPopoverController для представления контроллера вида. Вместо этого вы можете установить modalPresentationStyle контроллера вида на UIModalPresentationPopover.

Для этого можно использовать следующий код:

avc.modalPresentationStyle = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = theButton;
[self presentViewController:avc animated:YES completion:nil];

UIModalPresentationPopover

В горизонтально-обычной среде стиль презентации, где содержимое отображается в виде popover. Фоновый контент затушевывается и срабатывает за пределами причины popover popover для увольнения. Если вы не хотите, чтобы краны отклонили popover, вы можете назначить одно или несколько просмотров для passthroughViews свойство связанного объекта UIPopoverPresentationController, которые вы можете получить из свойства popoverPresentationController.

В горизонтально компактной среде эта опция ведет себя так же, как UIModalPresentationFullScreen.

Доступно в iOS 8.0 и более поздних версиях.

Ссылка Справка UIModalPresentationStyle


Вам нужно установить либо свойство sourceView, либо barButtonItem, иначе он выйдет из строя со следующим сообщением:

*** Завершение приложения из-за неперехваченного исключения "NSGenericException", причина: "UIPopoverPresentationController (***) должен иметь не-нуль sourceView или barButtonItem перед представлением. '

Чтобы привязать стрелку popover правильно, вам также нужно указать свойство sourceRect.

avc.modalPresentationStyle                   = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = self.view;
avc.popoverPresentationController.sourceRect = theButton.frame;
[self presentViewController:avc animated:YES completion:nil];

Подробнее см. sourceView и sourceRect.

Ответ 2

У Apple есть официальный способ представить и настроить popovers для iOS8 здесь: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html

В то время как похоже на ответ @MidhunMP, стоит отметить параграф:

Настройка контроллера представления popover после вызова presentViewController:animated:completion: может показаться контринтуитивный, но UIKit не создает контроллер представления пока вы не начнете презентацию. Кроме того, UIKit должен ждать пока следующий цикл обновления не покажет новое содержимое на экране. Эта задержка дает вам время для настройки контроллера презентации для ваш popover.

Конфигурация и ответ на события также могут быть выполнены через делегат, если вы хотите (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html).

Пример, отменив использование делегата:

// Present the controller using the popover style.
controller.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:controller animated:YES completion:nil];

// Popover presentation controller was created when presenting; now  configure it.
UIPopoverPresentationController *presentationController =
        [controller popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
presentationController.sourceView = containerFrameOfReferenceView;
// arrow points out of the rect specified here
presentationController.sourceRect = childOfContainerView.frame;

Но вы также захотите отклонить это. Чтобы сделать это без использования делегата, ваш контроллер может просто вызвать:

[self dismissViewControllerAnimated:YES completion:nil];

Но что, если я вращаю свое устройство, а popover не указывает на нужную область? Контроллер представления может справиться с этим:

// Respond to rotations or split screen changes
- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:nil 
                                 completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
        // Fix up popover placement if necessary, after the transition.
        if (self.presentedViewController) {
            UIPopoverPresentationController *presentationController =
                    [self.presentedViewController popoverPresentationController];
            presentationController.sourceView = containerFrameOfReferenceView;
            presentationController.sourceRect = childOfContainerView.frame;
        }
    }];
}

Ответ 3

Если требуется прямо из Button Action, этот код можно использовать

SecondViewController *destinationViewController = (SecondViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"second"];
destinationViewController.modalPresentationStyle = UIModalPresentationPopover;
destinationViewController.popoverPresentationController.sourceView = self.customButton;

// Set the correct sourceRect given the sender bounds
destinationViewController.popoverPresentationController.sourceRect = ((UIView *)sender).bounds;
[self presentViewController:destinationViewController animated:YES completion:nil];

Ответ 4

РЕДАКТИРОВАТЬ: Что касается нисходящих голосов. Сначала интересная и интересная история:

http://www.folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt

Я опубликовал ответ ниже, чтобы помочь программистам, которые, возможно, застряли в мышлении, что iPad/iPhone по-прежнему нуждаются в отдельных путях выполнения при представлении пользовательского интерфейса для выбора медиа. Во время моего оригинала В других ответах это не было ясно. Этот путь решения упростил мой код и будущее обслуживание моего приложения. Я думаю, что другие могут найти эту перспективу полезной, потому что иногда удаление правильных строк кода может быть хорошим решением.

Конец редактирования.

Если у вас уже есть рабочая программа и вы просто хотите избавиться от предупреждения об амортизации, это может сработать для вас.

В моем коде, и в моем понимании, Popovers были представлены для iPad и специфичны для iPad. Apple, похоже, изменила это. Итак, если у вас уже есть рабочая программа, которая использует что-то вроде этого:

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    // use popovers 
else
    //  don't use popovers

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