UIPopoverPresentationController на iPhone не создает popover
Я пытаюсь реализовать новый UIPopoverPresentationController
в своем iPhone-приложении (используя Objective C). То, что я хочу, - это простой popover с табличным представлением, который исходит от кнопки-инициатора.
- Edit -
Здесь мой ПЕРЕСМОТРЕННЫЙ код, адаптированный из исследований в документах, SO и от ввода комментариев ниже:
- (IBAction)selectCategoryBtn:(UIButton *)sender
{
[self performSegueWithIdentifier:@"CatSelectSegue" sender:self.selCatButton];
}
-(void) prepareForSegue:(UIStoryboardSegue *) segue Sender:(id) sender
{
if (sender == self.selCatButton)
{
if ([segue.identifier isEqualToString:@"CatSelectSegue"])
{
UIPopoverPresentationController *controller = segue.destinationViewController;
controller.delegate = self;
controller.sourceView = self.selCatButton;
controller.sourceRect = self.selCatButton.frame;
}
}
}
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
Здесь моя раскадровка:
![enter image description here]()
Однако это просто представляет табличное представление модальным образом, поднимаясь снизу и потребляя весь экран.
Я искал googled и выглядел повсюду, но похоже, что я не единственный, смущенный тем, что я надеялся разрешить проблему nettlesome для iPhone.
Может ли кто-нибудь увидеть сбой в моем коде или направить меня к четкому учебнику? Я посмотрел, но, возможно, API настолько новый, что у него еще нет ручек.
Спасибо!
2nd edit:
Вот что получается в результате приведенного выше кода. Я уменьшил размер табличного представления в контроллере просмотра, который, как я ожидал, будет представлен как popover. Я окрашивал фон в серый цвет, чтобы уточнить, что появляется вместо popover.
![enter image description here]()
Ответы
Ответ 1
Шаги:
A) Свяжите ваш UIButton
с контроллером просмотра popover с помощью типа Present As Popover
segue. Мне действительно нужно было создать новый проект, чтобы он появился, но это, вероятно, что-то связано с базовым SDK.
B) Сделайте контроллер View, содержащий UIButton
, соответствующим <UIPopoverPresentationControllerDelegate>
. Например. В файле MyViewController.m
добавьте:
@interface MyViewController () <UIPopoverPresentationControllerDelegate>
C) Добавьте метод ниже в контроллер просмотра, содержащий UIButton
:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
D) Добавьте в свою prepareForSegue:sender:
следующую замену:29 > :
if ([segue.identifier isEqualToString:@"CatSelectSegue"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *controller = dvc.popoverPresentationController;
if (controller) {
controller.delegate = self;
}
}
Проверен код и доказательство его работоспособности:
![Popover on iPhone without 3rd Party Controls]()
Изменить: Мое тестовое приложение Файл TPOPViewController.m, где происходит волшебство:
#import "TPOPViewController.h"
@interface TPOPViewController () <UIPopoverPresentationControllerDelegate>//, UIAdaptivePresentationControllerDelegate>
@end
@implementation TPOPViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifier = segue.identifier;
if ([identifier isEqualToString:@"popover"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *ppc = dvc.popoverPresentationController;
if (ppc) {
if ([sender isKindOfClass:[UIButton class]]) { // Assumes the popover is being triggered by a UIButton
ppc.sourceView = (UIButton *)sender;
ppc.sourceRect = [(UIButton *)sender bounds];
}
ppc.delegate = self;
}
}
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
@end
Моя тестовая раскадровка:
![Popover on iPhone test storyboard]()
Ответ 2
По-видимому, вышеуказанный метод больше не работает с iOS9/Xcode7. Это связано с тем, что если вы установили стиль segue в "Popover" с помощью Interface Builder, Xcode игнорирует его при компиляции вашего приложения. Кроме того, он автоматически устанавливает переход в режим "Push" при следующем открытии проекта. Если у вас есть программное обеспечение для управления версиями, например Git, вы сможете наблюдать за этим нежелательным изменением.
Тем не менее, все еще можно получить popovers на iPad в iPhone, если вы вручную представите контроллер вида, который вы хотите показать как popover. Пример кода Swift:
// ViewController.swift
// PopoverDemo
//
// Created by bhnascar on 12/2/15.
// Copyright © 2015 bhnascar. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
/* The bar button item that will present the popover. */
var popoverButton: UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
popoverButton = UIBarButtonItem(title: "Pop!", style: UIBarButtonItemStyle.Plain, target: self, action: "presentPopover")
self.navigationItem.rightBarButtonItem = popoverButton
}
// Mark: - UIPopoverPresentationControllerDelegate
func prepareForPopoverPresentation(popoverPresentationController: UIPopoverPresentationController) {
popoverPresentationController.permittedArrowDirections = .any
popoverPresentationController.barButtonItem = popoverButton
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
// Mark: - Callback function for popover button.
func presentPopover() {
let popoverContentController = UIViewController()
popoverContentController.view.backgroundColor = .blue
// Set your popover size.
popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)
// Set the presentation style to modal so that the above methods get called.
popoverContentController.modalPresentationStyle = .popover
// Set the popover presentation controller delegate so that the above methods get called.
popoverContentController.popoverPresentationController!.delegate = self
// Present the popover.
self.present(popoverContentController, animated: true, completion: nil)
}
}
Ответ 3
SWIFT 3.X
Это покажет поповер в центре экрана
class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{
func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle {
return .none
}
func showPopover() {
let myViewController = UIViewController()
myViewController.preferredContentSize = CGSize(width: 320, height: 200)
myViewController.modalPresentationStyle = .popover
let popOver = myViewController.popoverPresentationController
popOver?.delegate = self
self.present(myViewController, animated: true, completion: nil)
popOver?.permittedArrowDirections = .up
popOver?.sourceView = self.view
let rect = CGRect(
origin: CGPoint(x: self.view.frame.width/2,
y: self.view.frame.height/2),
size: CGSize(width: 1, height: 1)
)
popOver?.sourceRect = rect
}
}
Ответ 4
Представить UIModalPresentationStyle popover с iPhone/iPad:
-(void)menuButtonPressed:(UIButton *)sender {
self.menuPopoverController = [[DownloadMenuPopoverController alloc] initWithStyle:UITableViewStylePlain];
self.menuPopoverController.delegate = self;
self.menuPopoverController.modalPresentationStyle = UIModalPresentationPopover;
self.menuPopoverController.popoverPresentationController.delegate = self;
self.menuPopoverController.preferredContentSize = CGSizeMake(250,80);
self.menuPopoverController.popoverPresentationController.sourceRect = sender.frame;// rect to show view
self.menuPopoverController.popoverPresentationController.sourceView = self.view;
UIPopoverPresentationController *popPC = self.menuPopoverController.popoverPresentationController;
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popPC.delegate = self;
[self presentViewController:self.menuPopoverController animated:YES completion:nil];
}
#pragma mark - UIPresentationController Delegate methods
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
}
- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController];
return navController;
}