弹出框是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. Productivity tips, tricks and hacks for academics (2015 edition)

    Productivity tips, tricks and hacks for academics (2015 edition) Contents Jump to: My philosophy: Op ...

  2. 新手应知道的ASP.NET代码编写规范

    1.局部变量的名称要有意义,尽量用对应的英文命名,比如“用户姓名”变量,不要用aa bb cc等来命名,而要使用userName. 2.不要使用单个字母的变量,如i.n.x等.而要使用index.te ...

  3. 集合框架小结-Collection

    1.集合框架作为处理对象的容器存在,基本接口是Collection,相对于数组而言的话,集合框架只能存储对象,但是长度是可变的.集合框架的关系图如下: 主要的内容是list.set.map, List ...

  4. flex实例(阮一峰)

    Flex 布局教程:实例篇   作者: 阮一峰 日期: 2015年7月14日 上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法. 你会看到,不管是什么布局,Flex往往都可以几行命令 ...

  5. python初步学习-python模块之 logging

    logging 许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪.在python中,我们不需要第三方的日志组件,python为我们提供了简单易用.且 ...

  6. React Native 与 夜神模拟器的绑定

    之前一直用真机去调试, 每回更新一次都需要手动摇晃手机后才能reload JS, OMG,太麻烦了. 后来寻思模拟器网上推荐用Geny...什么的模拟器,但是那个模拟器还需要VBox一起用. 有点麻烦 ...

  7. JSON与JS的区别以及转换

    JSON是什么?(JSON和JavaScript对象有什么区别?)如何把JS对象转化为JSON字符串,又如何把JSON字符串转化为JavaScript对象? JSON (JavaScript Obje ...

  8. nginx配置不当导致的目录遍历下载漏洞-“百度杯”CTF比赛 2017 二月场

    题目:http://98fe42cede6c4f1c9ec3f55c0f542d06b680d580b5bf41d4.game.ichunqiu.com/login.php 题目内容: 网站要上线了, ...

  9. 64_p1

    PEGTL-devel-1.3.1-2.fc26.i686.rpm 13-Feb-2017 22:10 64086 PEGTL-devel-1.3.1-2.fc26.x86_64.rpm 13-Feb ...

  10. 使用navicat for sqlserver 把excel中的数据导入到sqlserver数据库

    以前记得使用excel向mysql中导入过数据,今天使用excel向sqlserver2005导入了数据,在此把做法记录一下 第一步:准备excel数据,在这个excel中有3个sheet,每个she ...