Pad控件 UIPopoverController的介绍与使用(Pad的专属菜单控件、Swift版本)
UIPopoverController 是iPad特有控件,iOS9之前,在iOS上也可以使用,在iOS9之后,只能用于Pad上。
如果非要在iOS上使用,编译不会有问题,运行后会崩溃,报错如下:
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UIPopoverController initWithContentViewController:] called when not running under UIUserInterfaceIdiomPad.'
因此,这里的介绍都是给予iPad来的,此文的Demo也得运行在Pad模拟器或pad真机上。
---------------------------------------------------------------------
如果想直接看最简单实现方式:
---------------------------------------------------------------------
下面是具体讲解。
1、关于UIPopoverController

其实就是类似图中这样的菜单弹出框。
在iOS上,我们可能要自己自定义或用三方封装好的菜单控件,但在pad上,我们可以直接使用系统提供的控件,简单快捷。
要想显示一个UIPopoverController,需要经过下列三步骤:
1)设置内容控制器:
由于UIPopoverController直接继承自NSObject,不具备可视化的能力,因此UIPopoverController上面的内容必须由另外一个继承自UIViewController的控制器来提供,这个控制器称为“内容控制器”
2)设置内容的尺寸:
显示出来占据多少屏幕空间
3)设置显示的位置:
从哪个地方冒出来
这里有几点注意 :
1、UIPopoverController不是一个view,不能直接显示或add到父view上,可以理解成一个盒子容器,盒子里面显示的内容需要一个额外的uiviewcontroller来呈现。
2、设置大小,最好在盒子里面的控制器来设置,每个uiviewcontroller都有一个 preferredContentSize 属性来设置size。
3、当然,如果想直接设置大小,也可以,不过如果内容控制器里设置了 preferredContentSize 大小 self.preferredContentSize = CGSizeMake(200, 200); 那么 self.popOver.popoverContentSize 将无意义。
2、属性介绍
设置内容的尺寸有2种方法:
@property (nonatomic) CGSize popoverContentSize; - (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated; 以上方法和属性都是UIPopoverController的
如果通过内容控制器设置内容尺寸
在iOS 7之前
@property (nonatomic,readwrite) CGSize contentSizeForViewInPopover; 从iOS 7开始
@property (nonatomic) CGSize preferredContentSize;
以上属性都是UIViewController的
常用属性
代理对象
@property (nonatomic, assign) id <UIPopoverControllerDelegate> delegate; 是否可见
@property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible; 箭头方向
@property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection; 关闭popover(让popover消失)
- (void)dismissPopoverAnimated:(BOOL)animated;
设置显示的位置
()围绕着一个UIBarButtonItem显示(箭头指定那个UIBarButtonItem) - (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated; item :围绕着哪个UIBarButtonItem显示 arrowDirections :箭头的方向 animated :是否通过动画显示出来 ()围绕着某一块特定区域显示(箭头指定那块特定区域) - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated; rect :指定箭头所指区域的矩形框范围(位置和尺寸),以view的左上角为坐标原点 view :rect参数是以view的左上角为坐标原点(,) arrowDirections :箭头的方向 animated :是否通过动画显示出来
代理方法
#pragma mark-代理方法
// popoverController消失的时候调用
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { }
// popoverController的位置改变的时候调用(如竖屏变横屏)
-(void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view { }
// 用来决定用户点击了蒙版后,popoverController是否可以dismiss,返回YES代表可以,返回NO代表不可以
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController {
return NO;
}
3、Demo代码介绍

一个是显示控制器文件
一个是popover的容器控制器文件
显示控制器:
var popOver:UIPopoverController!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
self.navigationItem.title = "必须用pad模拟器或pad测试"
let popVC = TestPopoverViewController()
popVC.delegate = self //代理为了点击内部的处理事件
//添加contentview子视图,大小建议在子视图内部设置
popOver = UIPopoverController(contentViewController: popVC)
popOver.delegate = self
//设置pop背景色,一般是为了和里面的content背景色一致,不然默认情况下会造成色差
popOver.backgroundColor = UIColor.white
//哪些控件可以继续跟用户进行正常交互。这样的话,点击区域外的控件就不会让UIPopoverController消失了
//popOver.passthroughViews = [view] //这句话加上后,点击蒙版,pop就不会消失,因为设置了view的交互可用
//导航点击弹出
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(self.testNavPop))
//按钮点击弹出
testBtnPop()
}
这里我构造了两种弹出方式:
1-导航栏位置 2-页面自定义位置,用一个按钮点击弹出


1-导航栏位置弹出
func testNavPop() {
popOver.present(from: self.navigationItem.leftBarButtonItem!, permittedArrowDirections: .any, animated: true)
}
2-按钮位置弹出
/// 在按钮弹出
func btnClick(sender:UIButton) {
//这种是紧靠着按钮位置弹出
//popOver.present(from: sender.bounds, in: sender, permittedArrowDirections: .any, animated: true) //自定义弹出位置,比如这里我设置y上面与按钮间隔20
popOver.present(from: CGRect(x: sender.bounds.origin.x, y: sender.bounds.origin.y+, width: sender.bounds.size.width, height: sender.bounds.size.height), in: sender, permittedArrowDirections: .any, animated: true) }
代理事件:
/// popover代理
extension TestPadViewController:UIPopoverControllerDelegate{
//popoverController消失的时候调用
func popoverControllerDidDismissPopover(_ popoverController: UIPopoverController) {
print("popoverControllerDidDismissPopover")
} //popoverController的位置改变的时候调用(如竖屏变横屏)
func popoverController(_ popoverController: UIPopoverController, willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>, in view: AutoreleasingUnsafeMutablePointer<UIView>) {
print("willRepositionPopoverTo")
} //用来决定用户点击了蒙版后,popoverController是否可以dismiss,返回YES代表可以,返回NO代表不可以
func popoverControllerShouldDismissPopover(_ popoverController: UIPopoverController) -> Bool {
return true
}
} /// popover容器内点击事件的代理
extension TestPadViewController:TestPopoverViewControllerDelegate{
internal func TestPopoverViewControllerDidSelect(index: NSInteger) {
popOver.dismiss(animated: true)
print("click \(index)")
} }
容器控制器:
var tableview:UITableView!
var data = ["列表1","列表2","列表3","列表4","列表5","列表6","列表7","列表8"]
weak var delegate:TestPopoverViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
//设置pop框最大高度为150
let maxH = min(, *data.count)
self.preferredContentSize = CGSize(width: , height: maxH)
tableview = UITableView(frame: self.view.bounds, style: .plain)
view.addSubview(tableview)
tableview.dataSource = self
tableview.delegate = self
tableview.estimatedRowHeight =
}
用一个列表做示例。

~~
Pad控件 UIPopoverController的介绍与使用(Pad的专属菜单控件、Swift版本)的更多相关文章
- 使用Duilib开发Windows软件(2)——控件的基本介绍
XML 先学习xml https://www.w3cschool.cn/xml/xml-xml-tutorialhc4o1t5m.html 控件 上图是我们下载的NIM_Duilib_Framewor ...
- ActiveX控件的基本操作方法以及如何在VS2010下使用控件
在此,小编就介绍下ActiveX控件的基本操作方法以及如何在VS2010下使用控件,我们以一个程序为例, (1) 打开VS2010编译器(右键以管理员身份运行,因为ActiveX需要注册), ...
- Asp.net 菜单控件
本文介绍的菜单控件采用的css 和ul list来显示菜单,生成的html小,无需javascript支持,对大部分的浏览器都支持,除ie6要单独修改css也可以使其支持. 通过本文可以了解asp.n ...
- 自写JQ控件-树状菜单控件[demo下载]
一个多月没有写博客了,最近也弄一个基于JQ的树状菜单控件,在此分享给大家.另外呢,通过这个例子分享一下怎么写JQ控件的. 事实上工作中,也是经常遇到的,有些时候自己想实现一些前端效果,用网上一些插件吧 ...
- 简洁的Asp.net菜单控件
http://www.cnblogs.com/ruinet/archive/2009/11/10/1599984.html asp.net自带的菜单控件采用的table和javascript,导致生成 ...
- Android 使用代码主动去调用控件的点击事件(模拟人手去触摸控件)
使用代码主动去调用控件的点击事件(模拟人手去触摸控件) //View 可以是LinearLayout,Button,TextView View.performClick();
- 实用的树形菜单控件tree
jQuery plugin: Treeview 这个插件能够把无序列表转换成可展开与收缩的Tree. jQuery plugin: Treeview jQuery jstree jsTree ...
- html树形菜单控件
html树形菜单控件 链接 http://www.ithao123.cn/content-713974.html jQuery plugin: Treeview 这个插件能够把无序 ...
- Android两个控件叠在一起,如何让被挡住的控件显示出来
Android两个控件叠在一起,如何让被挡住的控件显示出来 问题 : 两个控件叠在一起,如何让被挡住的控件显示出来? 比如A,B两个控件,A被B挡住,目前A要显示出来,B不能被隐藏,A的高度只有那么一 ...
随机推荐
- iOS Foundation框架 -1.常用结构体的用法和输出
1.安装Xcode工具后会自带开发中常用的框架,存放的地址路径是: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.plat ...
- 封装keyframes插件
模仿jquery,使用简单,自动添加浏览器前缀 var keyframes = new SHBKerframes(); keyframes.define([{ name:'myAnimate', 0% ...
- C++ 中的 delete[] 机制剖析
本文简单总结了delete[]放在析构函数中VS放在主函数中的区别(针对自己定义类). delete原理简单剖析(摘至https://zhidao.baidu.com/question/1540902 ...
- node-webkit制作桌面应用
心血来潮突然想用js尝试写桌面应用,突然发现我大js真的无所不能.在网上搜到了这么一个东东:node-webkit.用Node.js来进行系统资源的访问,用HTML+CSS完成页面的搭建.哇,一切突然 ...
- 2732: [HNOI2012]射箭( 半平面交 )
很久没写题解了= =,来水一发吧= = 首先这道题很明显就是求y=ax^2+bx的是否有值取,每一个式子都代表着两个半平面,然后直接半平面交就行了 借鉴了hzwer的代码,还是特别简洁的说 CODE: ...
- [译]如何在Web开发中使用Python
[译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...
- 强化学习读书笔记 - 02 - 多臂老O虎O机问题
# 强化学习读书笔记 - 02 - 多臂老O虎O机问题 学习笔记: [Reinforcement Learning: An Introduction, Richard S. Sutton and An ...
- 1647: [Usaco2007 Open]Fliptile 翻格子游戏
1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 423 Solved: 173[ ...
- Intelligent idea高效实用总结
一直使用eclipse,最近才转到idea IDE上面来,的确从效率等多个角度,idea都要优于eclipse.由于刚实用idea,不是很熟练,将常用的技巧总结集锦一下,方便以后查看,慢慢积累吧 一. ...
- 关于java泛型
<T> 代表的是泛型 ,实例化的时候将传入真正的数据类型,比如: public interface BaseProvider<T>{ public T test(); } 实例 ...