Как правильно представить popover в iOS 8


Я пытаюсь добавить UIPopoverView в мое приложение Swift iOS 8, но я не могу получить доступ к свойству PopoverContentSize, так как popover не отображается в правильной форме. мой код:

var popover: UIPopoverController? = nil 

    func addCategory() {

    var newCategory = storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: newCategory)
    popover = UIPopoverController(contentViewController: nav)
    popover!.setPopoverContentSize(CGSizeMake(550, 600), animated: true)
    popover!.delegate = self
    popover!.presentPopoverFromBarButtonItem(self.navigationItem.rightBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}

вывод:

когда я делаю то же самое через UIPopoverPresentationController, я все еще не делаю этого. это мой код:

func addCategory() {

    var popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController as UIPopoverPresentationController
    popover.delegate = self
    popover.popoverContentSize = CGSizeMake(1000, 300)
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

Я получаю точно такой же выход.

Как настроить размер моего popover? Любой помощь будет высоко оценена!

11 104

11 ответов:

хорошо, сосед по дому посмотрел на него и понял:

 func addCategory() {

    var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController
    popoverContent.preferredContentSize = CGSizeMake(500,600)
    popover.delegate = self
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

вот так.

вы больше не разговариваете с самим popover, вы разговариваете с контроллером вида внутри него, чтобы установить размер содержимого, вызвав свойство preferredContentSize

на самом деле это гораздо проще, чем. В раскадровке вы должны сделать viewcontroller вы хотите использовать в качестве popover и сделать viewcontroller класс для него, как обычно. Сделайте сегмент, как показано ниже, из объекта, который вы хотите открыть popover, в этом случае UIBarButton С именем "Config".

enter image description here

в "мать viewcontroller" реализовать UIPopoverPresentationControllerDelegate и метод делегата:

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
    //do som stuff from the popover
}

переопределить prepareForSeque метод, как это:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     //segue for the popover configuration window
    if segue.identifier == "yourSegueIdentifierForPopOver" {
        if let controller = segue.destinationViewController as? UIViewController {
            controller.popoverPresentationController!.delegate = self
            controller.preferredContentSize = CGSize(width: 320, height: 186)
        }
    }
}

и вы сделали. И теперь вы можете рассматривать представление popover как любое другое представление, т. е. добавьте поля, а что нет! И вы получите доступ к контроллеру содержимого с помощью popoverPresentationController.presentedViewController метод UIPopoverPresentationController.

также на iPhone вам придется перезаписать

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {

        return UIModalPresentationStyle.none
    } 

Я нашел полный пример того, как заставить все это работать, чтобы вы могли всегда отображение всплывающего окна независимо от устройства / ориентации https://github.com/frogcjn/AdaptivePopover_iOS8_Swift.

ключ заключается в реализации UIAdaptivePresentationControllerdelegate

func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle {
    // This *forces* a popover to be displayed on the iPhone
    return .None
}

затем расширьте пример выше (из Imagine Digital):

nav.popoverPresentationController!.delegate = implOfUIAPCDelegate

Swift 2.0

Ну я работал. Взглянуть. Сделал ViewController в раскадровке. Связанный с классом PopOverViewController.

import UIKit

class PopOverViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()    
        self.preferredContentSize = CGSizeMake(200, 200)    
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "dismiss:")    
    }    
    func dismiss(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}      

См. ViewController:

//  ViewController.swift

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
{
    func showPopover(base: UIView)
    {
        if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("popover") as? PopOverViewController {    

            let navController = UINavigationController(rootViewController: viewController)
            navController.modalPresentationStyle = .Popover

            if let pctrl = navController.popoverPresentationController {
                pctrl.delegate = self

                pctrl.sourceView = base
                pctrl.sourceRect = base.bounds

                self.presentViewController(navController, animated: true, completion: nil)
            }
        }
    }    
    override func viewDidLoad(){
        super.viewDidLoad()
    }    
    @IBAction func onShow(sender: UIButton)
    {
        self.showPopover(sender)
    }    
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return .None
    }
}  

Примечание: метод func showPopover(base: UIView) должен быть размещен перед ViewDidLoad. Надеюсь, это поможет !

в iOS9 UIPopoverController амортизируется. Поэтому можно использовать приведенный ниже код для версии Objective-C выше iOS9.x,

- (IBAction)onclickPopover:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UIViewController *viewController = [sb instantiateViewControllerWithIdentifier:@"popover"];

viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.popoverPresentationController.sourceView = self.popOverBtn;
viewController.popoverPresentationController.sourceRect = self.popOverBtn.bounds;
viewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:viewController animated:YES completion:nil]; }
-(void) popoverstart
{
    ViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"PopoverView"];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:controller];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = nav.popoverPresentationController;
    controller.preferredContentSize = CGSizeMake(300, 200);
    popover.delegate = self;
    popover.sourceView = self.view;
    popover.sourceRect = CGRectMake(100, 100, 0, 0);
    popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
    [self presentViewController:nav animated:YES completion:nil];
}

-(UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller
{
    return UIModalPresentationNone;
}

Не забудьте добавить
UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate

Это лучше всего объяснить на iOS8 день за днем блог

короче говоря, как только вы установите modalPresentationStyle вашего UIViewController .Popover, вы можете получить доступ к UIPopoverPresentationClass (новый класс iOS8) через свойство popoverPresentationController контроллера.

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

-(void) presentPopover
{
    YourViewController* popoverContent = [[YourViewController alloc] init]; //this will be a subclass of UIViewController
    UINavigationController* nav =  [[UINavigationController alloc] initWithRootViewController:popoverContent];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController* popover = nav.popoverPresentationController;
    popoverContent.preferredContentSize = CGSizeMake(500,600);
    popover.delegate = self;
    popover.sourceRect = CGRectMake(100,100,0,0); //I actually used popover.barButtonItem = self.myBarButton;

    [self presentViewController:nav animated:YES completion:nil];
}

реализовать UIAdaptivePresentationControllerdelegate в вашем Viewcontroller. Затем добавьте:

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
    return .none
}

мои два цента для xcode 9.1 / swift 4.

класс ViewController: UIViewController, UIPopoverPresentationControllerDelegate {

override func viewDidLoad(){
    super.viewDidLoad()


    let when = DispatchTime.now() + 0.5
    DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in
        // to test after 05.secs... :)
        self.showPopover(base: self.view)
    })

}


func showPopover(base: UIView)
{
    if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "popover") as? PopOverViewController {

        let navController = UINavigationController(rootViewController: viewController)
        navController.modalPresentationStyle = .popover

        if let pctrl = navController.popoverPresentationController {
            pctrl.delegate = self

            pctrl.sourceView = base
            pctrl.sourceRect = base.bounds

            self.present(navController, animated: true, completion: nil)
        }
    }
}


@IBAction func onShow(sender: UIButton)
{
    self.showPopover(base: sender)
}

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
    return .none
}

и эксперимент в:

func adaptivePresentationStyle...

    return .popover

или: возвращаться.лист бумаги.... и так далее..

Swift 3: В моем случае априори есть знание только о том, что базовый UIViewController является TextViewController (мое имя для UIViewController мне нужно popover), что это может быть popOverPresentationController и что он содержит NSMutableAttributedString.

это вся информация, необходимая для построения popOverPresentationController, чтобы быть правильным размером, используя размер NSMutableAttributedString, а затем устанавливая размер UIViewController к размеру строки, поставляемой к нему. Я создаю NSMutableAttributedString, устанавливаю его содержимое с помощью метода под названием "createStats()".

обратите внимание, что мне нужно установить предпочтительный размер содержимого базового UIViewController, поэтому я использую: tvc.preferredContentSize, чтобы установить его. UIViewController называется "tvc". Я использую ТВЦ.preferredContentSize = CGSizeFromString(строка (описание: myCreatedAttributedMutableString)).

мой popOverPresentationController (который является UIViewController) имеет textView. Поэтому в раскадровке я установил textView как "приписанный". Введите описание изображения здесь

textView имеет строку (называемую "операции"), которая доставляется ему с помощью segue. Эта строка ("операции") - это все содержимое, которое будет отображаться при появлении всплывающего окна.

поэтому мое решение заключается в использовании следующего в подготовке(для segue: ...)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let tvc = segue.destination as? TextViewController {
        if let ppc = tvc.popoverPresentationController {
            ppc.delegate = self
        }

        let returnStatsStr: NSMutableAttributedString = createStats()

        let myCreatedAttributedMutableString = NSMutableAttributedString.init()

        myCreatedAttributedMutableString.append(returnStatsStr)

        tvc.operations = myCreatedAttributedMutableString
        tvc.preferredContentSize = CGSizeFromString(String(describing: myCreatedAttributedMutableString))

    }

}

вот как он появляется, когда он появляется.

Введите описание изображения здесь