首先.大家使用iOS系统的时候肯定看到过类似于下图这样的UI效果,那么.这个效果叫啥嘞.
这这种效果叫popover.表现形式为一个小尖尖.再加上一个看上去是View的东东.
但是,其实,这个东西不是View,而是一个Controller.
比起alert之类的东西.popover可以明确的提醒用户,交互是在哪里发生的,就是靠这个小尖尖.有些软件上的"popover"其实是自定义的popover(一个三角加上一个View,比如支付宝首页的那个"+"号点击出来的框框).
在iOS9之前.使用类UIPopoverController来完成效果的,并且,这个UIPopoverController只支持iPad.iPhone是不支持的.iOS9之后的新类支持,这个我们下面会讲.
####前世:UIPopoverController(iOS9之前,仅支持iPad)
ipad屏幕较大,内容物过多,如果点击一个控件之后弹出一个alert让你选择不同的东西的话,可能就会忘记点的哪个控件弹出来的了.那么就需要一种新的弹出机制.其实个人感觉popover有新瓶装旧酒的嫌疑,毕竟这玩意太像PC可视化操作系统里面的菜单了.但是确实解决了不少的问题.
下面用Swift来讲解一下Popover的使用:
首先,点进文档就发现有这么一句注释:
说明这玩意是iOS3.2出的.然后9.0就废弃了.让我们使用UIPopoverPresentationController来代替.
open class UIPopoverController : NSObject, UIAppearanceContainer
说明UIPopoverController是继承于NSObject的,并且遵守了UIAppearanceContainer协议.那么就说明这个UIPopoverController是没有展示内容的能力的,那么就不能直接继承一个UIPopoverController然后去设置他的View=xxx
构造方法中有一个
public init(contentViewController viewController: UIViewController).这个contentViewController
是不是让你想起了Container(怎么拼写忘了).反正就是那个容器视图.
#####1.创建一个内容控制器
let vc: OldPopoverViewController = OldPopoverViewController()
#####2.然后使用init构建方法
let popoverVc: UIPopoverController = UIPopoverController(contentViewController: vc)
#####3.设置代理
//根据
popoverVc.delegate = self
#####4.设置属性
///这里是在点击跳转逻辑里面写的
//设置popover背景色(包括了小三角).建议把内容控制器的View的backgroundColor修改为clearColor.通过popoverVc的backgroundColor来修改整个的颜色
popoverVc.backgroundColor = .red
//使vc的size(View)使用Layout布局
vc.preferredContentSize = vc.view.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
//设置popover的size(内容视图大小,绑定于Vc)
popoverVc.contentSize = vc.preferredContentSize
///这里是在内容视图控制器里面写的,目的是控制内容视图大小
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//SnapKit设置约束版本
// view.snp.makeConstraints { (make) in
// make.width.equalTo(UIScreen.main.bounds.size.width / 5)
// make.height.equalTo(UIScreen.main.bounds.size.height / 5)
// }
//使用原生约束版本
view.translatesAutoresizingMaskIntoConstraints = false
view.addConstraint(NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.width, multiplier: 0, constant: UIScreen.main.bounds.size.width / 5))
view.addConstraint(NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.height, multiplier: 0, constant: UIScreen.main.bounds.size.height / 5))
}
#####5.present出来
######1.点击的是UIBarButtonItem或者是继承于UIBarButtonItem的控件
//present出popver.从tabbarItem上弹出来.小三角的方向为任何方向
popoverVc.present(from: sender, permittedArrowDirections:.any, animated: true)
######2.点击的是UIView或者是继承于UIView的控件
//present出popver.从任何继承与UIView的空间上弹出来.小三角的方向为任何方向
popoverVc.present(from: sender.bounds, in: sender, permittedArrowDirections: .any, animated: true)
GitHub对应地址
####今生:UIPopoverPresentationController(iOS9之后,支持iPad与iPhone,但是iPhone需要设置才能正确的Popover,不然就是普通的modal)
随着iPhone的发展,屏幕变得越来越大.苹果可能也是考虑到了这点儿,放松了对Popover使用的情况.终于,在iOS9我们迎来了iPhone能用的popover.不过使用的类也从之前的UIPopoverController变成了UIPopoverPresentationController,从之前一个单独的类.变成了:
extension UIViewController {///UIViewController的分类
@available(iOS 8.0, *)
open var presentationController: UIPresentationController? { get }
@available(iOS 8.0, *)
open var popoverPresentationController: UIPopoverPresentationController? { get }
}
创建的方法相应的变成了以下的样子
#####1.创建一个内容控制器
let popoverController: PopoverViewController = PopoverViewController()
#####2.指定modal展示为popover类型
popoverController.modalPresentationStyle = .popover
#####3.指定需要popover控制器的popover的代理
popoverController.popoverPresentationController?.delegate = self
#####4.设置相应的属性
popover有一个来源视图"souceView",如果是继承与UIView下的那就使用SourceView.如果是继承与UIResponder的UIBarButtonItem那就使用"barButtonItem"
######1.这是继承与UIBarButtonItem的
popoverController.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
######2.这是继承与UIView的
//不设置sourceRect其实是可以的,但是小尖尖的位置会不对
popoverController.popoverPresentationController?.sourceView = midPopOverBtn
//小尖尖位置
popoverController.popoverPresentationController?.sourceRect = midPopOverBtn.bounds
///和之前的UIPopoverController一样,也是有arrowDirection(小尖尖的位置)的说法.只不过到了popoverPresentationController属性里面去设置了,下面这么写只是为了让大家更好理解.设置的话还是建议大家去ViewDidLoad里面去写
popoverController.popoverPresentationController?.arrowDirection = .xxx(Any之类的)
#####5.设置大小,这个需要配合约束
popoverController.preferredContentSize = popoverController.view.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
#####6.present出相应的控制器
self.present(popoverController, animated: true, completion: nil)
#####代理方法的设置(重要,在以下方法里面设置让iPad和iPhone都使用popover的效果)
/// 解除iPhone不能使用popover的限制(如果不设置这个,ipad有popover效果,而iphone没有)
///
/// - Parameter controller: <#controller description#>
/// - Returns: <#return value description#>
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
#####控制器大小的控制器方的设置
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// MARK: 整个pop的背景色
self.popoverPresentationController?.backgroundColor = .red
// MARK: 设置View约束
view.snp.makeConstraints { (make) in
make.height.equalTo(UIScreen.main.bounds.size.height / 3)
make.width.equalTo(UIScreen.main.bounds.size.width / 3)
}
}