博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Pad控件 UIPopoverController的介绍与使用(Pad的专属菜单控件、Swift版本)
阅读量:5233 次
发布时间:2019-06-14

本文共 6222 字,大约阅读时间需要 20 分钟。

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 
delegate;是否可见@property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible;箭头方向@property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection;关闭popover(让popover消失)- (void)dismissPopoverAnimated:(BOOL)animated;

 

设置显示的位置

(1)围绕着一个UIBarButtonItem显示(箭头指定那个UIBarButtonItem)- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;item :围绕着哪个UIBarButtonItem显示arrowDirections :箭头的方向animated :是否通过动画显示出来 (2)围绕着某一块特定区域显示(箭头指定那块特定区域)- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;rect :指定箭头所指区域的矩形框范围(位置和尺寸),以view的左上角为坐标原点view :rect参数是以view的左上角为坐标原点(0,0)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+20, 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
, in view: AutoreleasingUnsafeMutablePointer
) { 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(150, 40*data.count)                self.preferredContentSize = CGSize(width: 200, height: maxH)                        tableview = UITableView(frame: self.view.bounds, style: .plain)        view.addSubview(tableview)        tableview.dataSource = self        tableview.delegate = self        tableview.estimatedRowHeight = 40            }

用一个列表做示例。

 

 

 

~~

转载于:https://www.cnblogs.com/yajunLi/p/6639339.html

你可能感兴趣的文章
如何解除循环引用
查看>>
android中fragment的使用及与activity之间的通信
查看>>
jquery的contains方法
查看>>
python3--算法基础:二分查找/折半查找
查看>>
Perl IO:随机读写文件
查看>>
转:基于用户投票的排名算法系列
查看>>
WSDL 详解
查看>>
[转]ASP数组全集,多维数组和一维数组
查看>>
C# winform DataGridView 常见属性
查看>>
逻辑运算和while循环.
查看>>
Nhiberate (一)
查看>>
c#后台计算2个日期之间的天数差
查看>>
安卓开发中遇到的小问题
查看>>
ARTS打卡第3周
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
cookies相关概念
查看>>
CAN总线波形中ACK位电平为什么会偏高?
查看>>
MyBatis课程2
查看>>
桥接模式-Bridge(Java实现)
查看>>
svn客户端清空账号信息的两种方法
查看>>