在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右边的空心圆圈拉线到我们希望箭头指到的视图即可。
网友评论