【问题标题】:UIPopoverPresentationController on iPhone with iOS 10带有 iOS 10 的 iPhone 上的 UIPopoverPresentationController
【发布时间】:2017-05-18 06:30:01
【问题描述】:

我正在尝试将 ViewController 显示为 iPhone 上的弹出框。我已经在 SO 和其他网络上浏览过几个答案,但到目前为止都没有。我编写了一个简单的应用程序来测试它。

ViewController.swift:

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(clicked(_:)))
    }

    func clicked(_ sender: Any) {
        let vc = UIViewController()
        vc.view.backgroundColor = UIColor.blue
        vc.preferredContentSize = CGSize(width: 200, height: 200)
        vc.modalPresentationStyle = .popover
        present(vc, animated: true, completion: nil)

        let ppc = vc.popoverPresentationController
        ppc?.permittedArrowDirections = .any
        ppc?.delegate = self
        ppc?.barButtonItem = navigationItem.rightBarButtonItem
    }

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

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

故事板在 NavigationController 中嵌入了一个空的 ViewController。

运行这个,我希望弹出视图控制器显示在“完成”按钮下。相反,蓝色视图控制器全屏显示。

有没有办法改变这种行为?

【问题讨论】:

  • 您必须设置sourceViewsourceRect 例如ppc?.sourceView = sender as! UIView
  • @Bilal ppc?.barButtonItem = navigationItem.rightBarButtonItem 负责这一点

标签: ios iphone swift uipopovercontroller


【解决方案1】:

您在呈现视图后连接代理。它将如何从委托返回 .none 并显示为弹出框。使用这个:-

    func clicked(_ sender: Any) {

        let vc = UIViewController()
        vc.view.backgroundColor = UIColor.blue
        vc.modalPresentationStyle = .popover

        vc.preferredContentSize = CGSize(width: 200, height: 200)

        let ppc = vc.popoverPresentationController
        ppc?.permittedArrowDirections = .any
        ppc?.delegate = self
        ppc?.barButtonItem = navigationItem.rightBarButtonItem
        ppc?.sourceView = sender

        present(vc, animated: true, completion: nil)

    }

【讨论】:

    【解决方案2】:
    import UIKit
    class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
    
    override func viewDidLoad() {
            super.viewDidLoad()
            navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(clicked(_:)))
        }
    
    
    
    func clicked(_ sender: Any) {
            let vc = UIViewController()
            vc.view.backgroundColor = UIColor.blue
            vc.preferredContentSize = CGSize(width: 200, height: 200)
            vc.modalPresentationStyle = .popover
            let ppc = vc.popoverPresentationController
            ppc?.permittedArrowDirections = .any
            ppc?.delegate = self
            ppc!.sourceView = sender as? UIView 
            ppc?.barButtonItem = navigationItem.rightBarButtonItem
            present(vc, animated: true, completion: nil)
        }
    
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
            return .none
        }
    
    
    }
    

    【讨论】:

      【解决方案3】:

      上述解决方案在最新的 iOS 12 及更高版本中不再有效。要让它再次工作,请在 viewController 中覆盖 -modalPresentationStyle 以显示为弹出框并返回 UIModalPresentationPopover。 另外提供popoverPresentationController.delegate,实现adaptivePresentationStyleForPresentationController:traitCollection:并返回UIModalPresentationNone

      @interface PopoverViewController : UIViewController
      @end
      
      @implementation PopoverViewController
      
      - (UIModalPresentationStyle)modalPresentationStyle
      {
          return UIModalPresentationPopover;
      }
      
      @end
      
      @interface ViewController ()<UIPopoverPresentationControllerDelegate>
      @end
      
      @implementation ViewController
      
      - (IBAction)openPopover:(id)sender
      {
          UIViewController* testVC = [[PopoverViewController alloc] init];
          testVC.view.backgroundColor = UIColor.yellowColor;
          UIPopoverPresentationController* popPresenter = [testVC popoverPresentationController];
          popPresenter.permittedArrowDirections = UIPopoverArrowDirectionUp;
          popPresenter.delegate = self;
          popPresenter.sourceView = sender;
          popPresenter.sourceRect = [sender bounds];
          [self presentViewController:testVC animated:YES completion:^{}];
      }
      
      #pragma mark protocol (UIPopoverPresentationControllerDelegate)
      
      - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
      {
          return UIModalPresentationNone;
      }
      
      @end
      

      【讨论】:

        【解决方案4】:

        添加:

        vc.popoverPresentationController?.delegate = self 
        

        就在该行之前:

        present(vc, animated: true, completion: nil)
        

        【讨论】:

          猜你喜欢
          • 2014-10-08
          • 2017-05-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多