Popover前世今生

首先.大家使用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)
	}
}

GitHub对应地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值