UIPopoverPresentationController на iOS 8 iPhone
Кто-нибудь знает, можно ли использовать UIPopoverPresentationController
для представления popovers на iPhone? Интересно, добавила ли Apple эту функцию на iOS 8 в своей попытке создать более унифицированные контроллеры презентаций для iPad и iPhone.
Не уверен, что его ОК, чтобы спросить/ответить на вопросы из бета-версии. Я удалю его в этом случае.
Ответы
Ответ 1
Вы можете переопределить адаптивное поведение по умолчанию (UIModalPresentationFullScreen
в компактной горизонтальной среде, то есть iPhone), используя
adaptivePresentationStyleForPresentationController:
доступен через UIPopoverPresentationController.delegate
.
UIPresentationController
использует этот метод для запроса нового стиля презентации, который в вашем случае просто возвращает UIModalPresentationNone
приведет к тому, что UIPopoverPresentationController
будет отображаться как popover вместо полноэкранного.
Вот пример popover, использующий настройку segue в раскадровке от UIBarButtonItem
до " присутствует модально" a UIViewController
class SomeViewController: UIViewController, UIPopoverPresentationControllerDelegate {
// override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { // swift < 3.0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "PopoverSegue" {
if let controller = segue.destinationViewController as? UIViewController {
controller.popoverPresentationController.delegate = self
controller.preferredContentSize = CGSize(width: 320, height: 186)
}
}
}
// MARK: UIPopoverPresentationControllerDelegate
//func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle { // swift < 3.0
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
// Return no adaptive presentation style, use default presentation behaviour
return .None
}
}
Этот трюк был упомянут в сессии WWDC 2014 214 "Продвижение контроллера в iOS8" (36:30)
Ответ 2
Если кто-то хочет представить popover только с кодом, вы можете использовать следующий подход.
ЦЕЛЬ - C
Объявить свойство UIPopoverPresentationController
:
@property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;
Используйте следующий метод для представления popover из UIButton:
- (IBAction)btnSelectDatePressed:(id)sender
{
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
_dateTimePopover8.sourceRect = sender.frame;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];
}
Используйте следующий метод для представления popover из UIBarButtonItem:
- (IBAction)btnSelectDatePressed:(id)sender
{
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
CGRect frame = [[sender valueForKey:@"view"] frame];
frame.origin.y = frame.origin.y+20;
_dateTimePopover8.sourceRect = frame;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];
}
Внедрите этот метод делегата в свой контроллер:
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}
Чтобы отклонить этот popover, просто отпустите контроллер вида. Ниже приведен код для отклонения контроллера вида:
-(void)hideIOS8PopOver
{
[self dismissViewControllerAnimated:YES completion:nil];
}
СВИФТ
Используйте следующий метод для представления popover из UIButon:
func filterBooks(sender: UIButon)
{
let filterVC = FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil)
var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205)
let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Any
popoverPresentationViewController?.delegate = self
popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
popoverPresentationViewController!.sourceView = self.view;
popoverPresentationViewController!.sourceRect = sender.frame
filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
filterDistanceViewController.navigationBarHidden = true
self.presentViewController(filterDistanceViewController, animated: true, completion: nil)
}
Используйте следующий метод для представления popover из UIBarButtonItem:
func filterBooks(sender: UIBarButtonItem)
{
let filterVC = FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil)
var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205)
let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Any
popoverPresentationViewController?.delegate = self
popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
popoverPresentationViewController!.sourceView = self.view;
var frame:CGRect = sender.valueForKey("view")!.frame
frame.origin.y = frame.origin.y+20
popoverPresentationViewController!.sourceRect = frame
filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
filterDistanceViewController.navigationBarHidden = true
self.presentViewController(filterDistanceViewController, animated: true, completion: nil)
}
Внедрите этот метод делегата в свой контроллер:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle{
return .None
}
Обязательно добавьте делегат UIPopoverPresentationControllerDelegate
в .h/.m/.swift файл
Ответ 3
ПРОБЛЕМА: iPhone popover отображает полноэкранный режим и не учитывает значение preferredContentSize.
РЕШЕНИЕ: В отличие от того, что предлагает Apple в описании класса UIPopoverPresentationController, представление контроллера представления после получения ссылки на контроллер представления popover и его настройка.
// Get the popover presentation controller and configure it.
//...
// Present the view controller using the popover style.
[self presentViewController:myPopoverViewController animated: YES completion: nil];
Ответ 4
Я нашел некоторое обходное решение.
В Xcode6.1 используйте presentationController.delegate
вместо popoverPresentationController.delegate
.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier compare:@"showPopOver"] == NSOrderedSame) {
UINavigationController * nvc = segue.destinationViewController;
UIPresentationController * pc = nvc.presentationController;
pc.delegate = self;
}
}
#pragma mark == UIPopoverPresentationControllerDelegate ==
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
}
В WWDC 2014 "Просмотр улучшений контроллера в iOS8", ниже коды могут показывать popover на iPhone.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UINavigationController * nvc = segue.destinationViewController;
UIPopoverPresentationController * pvc = nvc.popoverPresentationController;
pvc.delegate = self;
}
#pragma mark == UIPopoverPresentationControllerDelegate ==
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
}
Но на Xcode 6.1 эти коды показывают презентацию FullScreen...
(nvc.popoverPresentationController равен нулю)
Я сомневаюсь, что это может быть ошибка Apple.
Ответ 5
Обязательно реализуйте UIAdaptivePresentationControllerDelegate
вот так:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
Если вам не нужны всплывающие окна с полным экраном
Ответ 6
В iOS 8.3 и более поздних версиях используйте следующий синтаксис в протоколе UIPopoverPresentationControllerDelegate
, чтобы переопределить всплывающее окно UIModalPresentationStyle
.
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
Ответ 7
добавьте эти два метода в свой класс WEBVIEW. и добавьте
-(void) prepareForSegue: (UIStoryboardSegue * ) segue sender: (id) sender {
// Assuming you've hooked this all up in a Storyboard with a popover presentation style
if ([segue.identifier isEqualToString: @"showPopover"]) {
UINavigationController * destNav = segue.destinationViewController;
pop = destNav.viewControllers.firstObject;
// This is the important part
UIPopoverPresentationController * popPC = destNav.popoverPresentationController;
popPC.delegate = self;
}
}
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}