在 iPhone & iPad 上显示 popover 弹出视窗

2019-12-26  本文已影响0人  久百一
image.png

在iPad上我们时常看到如上图红色框的弹出窗口弹出窗口,它可以让原本占满整个萤幕的控制器。画面瘦身,变成只占满萤幕的一部分。这样子的功能其实不是iPad独有,iPhone也做得到。接下来就让我们一步步实现popover的效果吧。

|在iPad上显示Popover

我们希望点选+后,选择角色的表格以popover呈现。


image.png

就像魔法一样,只要拉segue时选择Present As Popover即可实现拖放视窗的效果。


image.png image.png

然而同样的程式,跑在iPhone上却让我们明白童话都是骗人的。按了+之后,表格还是占满整个萤幕

image.png

其实iPhone还是能够做到popover,只是比较麻烦。我们还要加入以下程序。
+-----------------------------------------------------------------
1将第一页的控制器设为UIPopoverPresentationController物件的委托。

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
   override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         segue.destination.popoverPresentationController?.delegate = self
   }

当我们以popover方式呈现第二页的表控制器时,此时将自动生成UIPopoverPresentationController对象帮忙控制popover。而我们可通过定义UIPopoverPresentationControllerDelegate的功能控制popover。

因此我们让第一页的控制器遵从协议UIPopoverPresentationControllerDelegate,然后在功能中准备里利用segue.destination.popoverPresentationController读取UIPopoverPresentationController对象,然后将控制器设置成它的委托。
+-----------------------------------------------------------------
2定义UIPopoverPresentationControllerDelegate的函数adaptivePresentationStyle(for:traitCollection :)

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

为了让iPhone也能显示popover,我们必须在此方法里回传演示样式.none。


image.png

|------修改 Popover 的大小
修改popover显示的controller的preferredContentSize,即可控制popover的大小。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   segue.destination.preferredContentSize = CGSize(width: 150, height: 200)
   segue.destination.popoverPresentationController?.delegate = self
}
image.png

|-------从程序present controller实现popover的效果
我们也可以不透过segue,从程式present controller实现popover的效果。
以iPad App为例:

@IBAction func buttonPressed(_ sender: Any) {
 if let controller = storyboard?.instantiateViewController(withIdentifier: "TableViewController") {
   controller.modalPresentationStyle = .popover
   controller.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
   present(controller, animated: true, completion: nil)
 }
}

说明:
1 controller.modalPresentationStyle = .popover
以popover的效果呈现。
2 controller.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
让popover的箭头指到rightBarButtonItem。


image.png

|------让popover的箭头指到某个特定的视图。
刚刚我们透过barButtonItem指定popover的箭头指到bar上按钮,但我们也可利用sourceView让它指向某个特定的视图。

@IBAction func buttonPressed(_ sender: Any) {
   if let controller = storyboard?.instantiateViewController(withIdentifier: "TableViewController") {
      controller.modalPresentationStyle = .popover
      controller.popoverPresentationController?.sourceView = eyeSwitch
      present(controller, animated: true, completion: nil)
   }
}
image.png

如上图所示,现在箭头完美地指到开关。可惜它有个小小的缺点,它指到了开关的左上方,因为popover可以会指到sourceView的左上方。
没关系,只要设定UIPopoverPresentationController的sourceRect,即可控制箭头指到的位置。

controller.popoverPresentationController?.sourceRect = CGRect(origin: .zero, size: eyeSwitch.frame.size)
image.png

|--------从segue控制popover箭头指向到的对象。
从segue也可以设定popover箭头指向到的对象。如下图所示,Anchor栏位代表箭头指到的对象,因此从Anchor右边的空心圆圈拉线到我们希望箭头指到的视图即可。

image.png
上一篇 下一篇

猜你喜欢

热点阅读