弹出框是iPad的常用UI元素,即在现有视图上面显示内容,并通过一个小箭头指向一个屏幕对象(如按钮),以提供上下文。

和模态场景一样,弹出框的内容也由一个视图和一个试图控制器决定,不同之处在于,弹出框还需要另一个控制器对象--弹出框控制器(UIPopoverController)。该控制器指定弹出框的大小及其箭头指向何方。用户使用完弹出框后,只要触摸弹出框外面就可以自动关闭它。

如果是以拖拽的方式创建弹出切换,应该选择切换类型为"Popover",当这样选择后,发现可以调整视图的大小了;同时Interface Builder编辑器将该场景顶部的状态栏删除了,视图显示为一个平淡的矩形。这是因为弹出框作为一个小窗口显示在另一个视图上面,因此状态栏没有意义。

对于弹出框,Apple允许的最大宽度为600像素,但建议宽度不超过320像素;而允许的最大高度与iPad屏幕相同。

在编辑器中,可以通过"Directions"来设置箭头所指方向,例如设置为"left",则箭头指向左边,弹出框显示在元素右边。"Anchor"选项用来设置弹出框锚住的UI元素。"Passthrough"用来设置点击哪些元素后,弹出框并不消失。

手工显示弹出框仍然是调用performSegueWithIdentifier:sender。但是要注意的是,箭头并不指向sender参数提供的对象。所以只能以编程方式启动弹出切换,但必须在Interface Builder中将其关联到一个界面元素。

对于弹出框,是没有模态视图的presentingViewController和presentedViewController属性的,所以要在父视图中获取弹出框视图,必须通过prepareForSegue:sender方法。调用该方法后,先获取弹出框的专有控制器UIPopoverController实例,例如:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"toEditPopover"])
{
//将通用切换UIStoryboardSegue转换成弹出切换UIStoryboardPopoverSegue
UIStoryboardPopoverSegue *popoverSegue = (UIStoryboardPopoverSegue *)segue;
//弹出切换有一个属性"popoverController"来获取弹出框控制器UIPopoverController
UIPopoverController *popoverController = popoverSegue.popoverController;
//设置该控制器的delegate为自身类,用来处理弹出框关闭事件popoverControllerDidDismissPopover
popoverController.delegate = self;
//通过属性"contentViewController"可以获得弹出框实例
EditController *editVC = (EditController *)popoverController.contentViewController;
}
}

弹出框关闭时,父视图控制器是无法直接获悉的。要捕获弹出框关闭时的事件并获取相关内容,需要在父视图里遵守协议UIPopoverControllerDelegate。该协议提供了一个方法popoverControllerDidDismissPopover,可通过实现它来响应弹出框关闭。在这个方法中,还可获取弹出框的内容视图器,并访问其属性。(另一个方法是通过UIViewController的方法viewWillDisppear,这个方法在视图控制器的内容从屏幕上删除(就弹出框而言,是弹出框关闭)时被调用。)

popoverControllerDidDismissPopover方法接受一个参数:弹出框的UIPopoverController。通过该对象的"contentViewController"属性可以获取弹出框的视图控制器。这个代理类方法用来处理多个弹出框关闭事件,要分辨contentViewController指向的对象属于哪个类,可以调用弹出框的isMemberOfClass来判断,例如:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
if([popoverController.contentViewController isMemberOfClass:[EditController class]])
{
EditController *editVC = (EditController *)popoverController.contentViewController;
//do something...
}
}

要以编程方式创建并显示弹出框,必须先创建并配置UIPopoverController,然后调用UIPopoverController的initWithContentViewController来关联弹出框实例,最后调用UIPopoverController的presentPopoverFromRect : inView : permittedArrowDirections : animated方法显示弹出框。

第一步要先取得弹出框实例:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
EditController *editVC = [storyboard instantiateViewControllerWithIdentifier:@"myEdit"];

然后开始创建并配置UIPopoverController:

在iOS 5 和 Xcode 4.2(启用了ACR)中,有时会出现这样的问题:分配并初始化对象后,在我们需要使用前它们就被ACR释放了。这种情形不会经常发生,但一旦发生,应用程序就将崩溃,虽然从技术上说代码是正确的。为避免这种问题,可声明一个实例变量/属性,并让它指向要保留的对象。这种引用将避免ARC将该对象释放,从而确保一切按预期进行。

而UIPopoverController就是这种问题的受害者。如果您在同一个方法中声明、分配、配置和显示UIPopoverController,应用程序将崩溃。为了避免这种问题,将把它声明为一个属性:

@property (strong, nonatomic) UIPopoverController *editPopoverController;
@synthesize editPopoverController;

并在ViewController.m的方法viewDidUnload中执行清理工作,将该属性设置为nil:

- (void)viewDidUnload
{
[self setEditPopoverController:nil];
[super viewDidUnload];
}

然后关联弹出框实例:

self.editPopoverController = [[UIPopoverController alloc] initWithContentViewController:editVC];

接下来,使用UIPopoverController的属性popoverContentSize设置弹出框的宽度和高度。这个属性实际上是一个CGSize结构,该结构包含宽度和高度。为创建合适的CGSize结构,可使用函数CGSizeMake(),例如下面的代码将弹出框设置为宽300,高400:

self.editPopoverController.popoverContentSize = CGSizeMake(, );

在显示弹出框之前,需要完成的最后一步是,设置弹出框控制器的委托,让弹出框控制器自动调用协议UIPopoverControllerDelegate定义的方法popoverControllerDidDismissPopover:

self.editPopoverController.delegate = self;

显示弹出框需要调用UIPopoverController的方法presentPopoverFromRect : inView : permittedArrowDirections : animated,各参数说明如下:

第一个参数是设定弹出框指向的对象范围,格式为CGRect,一般设置为((UIView *)sender).frame。因为添加到视图中的任何对象都是UIView的子类,而UIView类有一个frame属性来标示对象的范围。

第二个参数inView指向显示弹出框的视图。由于我们假定从ViewController类中显示该弹出框,因此将其设置为self.view。

第三个参数permittedArrowDirections用来设置箭头可指向的方向。有如下常量:
UIPopoverArrowDirectionAny -- 箭头可指向任何方向,这给iOS在确定如何显示弹出框时提供了最大的灵活性。
UIPopoverArrowDirectionUp -- 箭头只能指向上方,这意味着弹出框必须位于对象下方。
UIPopoverArrowDirectionDown -- 箭头只能指向下方,这意味着弹出框必须位于对象上方。
UIPopoverArrowDirectionLeft -- 箭头只能指向左方,这意味着弹出框必须位于对象右边。
UIPopoverArrowDirectionRight -- 箭头只能指向右方,这意味着弹出框必须位于对象左边。
Apple建议尽可能使用常量UIPopoverArrowDirectionAny。显示弹出框时,可结合使用多个箭头方向,方法是使用管道线( | )分割这些常量。

第四个参数animated设置是否以动画的方式显示,通常为YES。

代码演示如下:

- (IBAction)testSomething:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
EditController *editVC = [storyboard instantiateViewControllerWithIdentifier:@"myEdit"]; self.editPopoverController = [[UIPopoverController alloc] initWithContentViewController:editVC];
self.editPopoverController.popoverContentSize = CGSizeMake(, );
self.editPopoverController.delegate = self; [self.editPopoverController presentPopoverFromRect:((UIView *)sender).frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

iPad弹出框的更多相关文章

  1. JavaScript插件——弹出框

    (JavaScript插件——弹出框) 前言 阅读之前您也可以到Bootstrap3.0入门学习系列导航中进行查看http://www.cnblogs.com/aehyok/p/3404867.htm ...

  2. Bootstrap入门(二十九)JS插件6:弹出框

    Bootstrap入门(二十九)JS插件6:弹出框 加入小覆盖的内容,像在iPad上,用于存放非主要信息 弹出框是依赖于工具提示插件的,那它也和工具提示是一样的,是需要初始化才能够使用的 首先我们引入 ...

  3. javascript基于对象的弹出框封装

    先睹为快,移动端:戳这里,打开页面后点击投票查看效果.PC端测试直接切换body的overflow属性:hidden和auto一样可以,比下面相对简化,又有人说这样偶尔不行..如果你知道优缺点欢迎给出 ...

  4. echart 时间轴、以及y轴值过大但是变化不大显示感觉不出变化的问题+弹出框拖动div事件

    1.时间轴 echart 提供了一种图表,如果x轴是一个时间范围,并且是连续的,如果用传统的数据驱动会很慢,所以用时间轴的方式 function initCurve(_data){ var resul ...

  5. 微信公众号弹出框在IOS最新系统中点击键盘上的“完成”导致事件无法触发问题

    微信公众号弹出框在IOS最新系统中点击键盘上的"完成"导致事件无法触发问题 问题描述 微信公众号中有项功能是弹框模态框,输入信息后保存操作.但是在IOS系统中发现,当输入内容后,点 ...

  6. 弹出框 popover.js

    弹出框 popover.js 为任意元素添加一小块浮层,就像 iPad 上一样,用于存放非主要信息. 弹出框的标题和内容的长度都是零的话将永远不会被显示出来. 插件依赖 弹出框依赖 工具提示插件 ,因 ...

  7. 关于Layer弹出框初探

    layer至今仍作为layui的代表作,她的受众广泛并非偶然,而是这五年多的坚持,不断完善和维护.不断建设和提升社区服务,使得猿们纷纷自发传播,乃至于成为今天的Layui最强劲的源动力.目前,laye ...

  8. angularjs 弹出框 $modal

    angularjs 弹出框 $modal 标签: angularjs 2015-11-04 09:50 8664人阅读 评论(1) 收藏 举报  分类: Angularjs(3)  $modal只有一 ...

  9. 【代码笔记】iOS-自定义弹出框

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [s ...

随机推荐

  1. 用英文写Email的注意事项

  2. SpringCloud(四)服务发现与消费:以ribbon为例

    说明: ribbon是spring-cloud中作为服务消费者的一种角色,客户端可以通过它来对服务提供者的服务进行消费, 比如本例中是服务提供者注册到注册中心,服务提供者提供了一个服务接口,返回一个h ...

  3. 【BZOJ】4293: [PA2015]Siano 线段树上二分

    [题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...

  4. python初步学习-生成式、生成器、迭代器、装饰器

    生成式 列表生成式 字典生成式 集合生成式 嵌套列表生成式 列表生成式 列表生成式是python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理.语法格式为 ...

  5. 通过cordova将vue项目打包为webapp

    准备工作:需要之前配置好vue-cli脚架构,安装好cordova环境.下面开始对vue.js项目进行打包,打包环境为Android. 可以看下我的github:https://github.com/ ...

  6. 一款已上市MMO手游地图同步方案总结

    1. 客户端地图格子的相关知识 在2.5D的MMO游戏里,角色是通过3D的方式渲染,2D的地图是通过2D的方式显示,所以在客户端一般会有三个坐标系: a) 3D坐标系:所有需要3D渲染的角色和光效,都 ...

  7. 004_Gradle 笔记——Java构建入门

    Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它 们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建 ...

  8. kvm安装准备

    到实际情况下,做虚拟化是直接做在真机上. 但实验时,可以在虚拟机上进行.(因为做实验的时候没办法连接到桥接模式的网络,所以使用了NAT方式来连接网络) 在vmware安装centos 64bit fo ...

  9. mac 卸载 node并重新安装

    系统升级到 Sierra 之后,npm 经常出问题,最终把 node 卸载了,安装了新版本.mac 卸载 node 比较麻烦,stackoverflow 上面找到一个方法还不错,特地记录下来,代码如下 ...

  10. Nginx - 隐藏或修改版本号

    1. 前言 无论是修改 Nginx 版本还是隐藏 Nginx 版本号,都是很简单的操作,对外来说,相对更安全些. 2. 修改 Nginx 版本号 对于修改 Nginx 版本号来说,需要在源码的基础上进 ...