很多App里都有一种点击显示的悬浮气泡菜单,例如下图:

在iPad上可以使用UIPopoverController实现这个功能,popoverController继承自NSObject而不是UIView,这是因为它本身并不能显示,popoverController的显示内容取决于成员属性contentViewController,并且该属性必须在初始化时被传入,否则会崩溃。

popover的尺寸应该由contentView决定,而不应该在外部设置,下面的代码实现了一个contentView,用于popover显示一个类似上图的菜单。

使用self.preferredContentSize属性来决定popover的尺寸。

//
// TableViewController.m
// iPad初步
//
// Created by 11 on 8/4/15.
// Copyright (c) 2015 soulghost. All rights reserved.
// #import "TableViewController.h" @interface TableViewController () @property (nonatomic, strong) NSMutableArray *menuList; @end @implementation TableViewController - (void)viewDidLoad {
[super viewDidLoad]; self.title = @"菜单"; CGFloat width = self.menuList.count * 44;
// 过期的方法self.contentSizeForViewInPopover需要计算导航控制器的标题宽度44,在iOS8不可用。
self.preferredContentSize = CGSizeMake(self.view.bounds.size.width * 0.5, width); } - (NSMutableArray *)menuList{ if (_menuList == nil) {
_menuList = [NSMutableArray arrayWithObjects:@"文件",@"编辑",@"设置",@"返回",nil];
} return _menuList; } #pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return self.menuList.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
} // 在这里设置cell数据
cell.textLabel.text = self.menuList[indexPath.row]; return cell; } @end

创建popoverView后,在iOS7如果不主动对其进行强引用会使得popoverView在显示时被释放,因此需要指定一个成员属性防止其释放;在iOS8和以后,即使不强引用也可以,但是为了适配,应该指定这个成员属性。

下面的代码演示了一个popoverView的创建:

- (IBAction)menuClick:(id)sender {

    // 创建Popover的显示内容(View)。
TableViewController *tvc = [[TableViewController alloc] init];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:tvc]; // 创建Popover,确定内容,确定尺寸,指定显示位置。
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:nvc];
_popoverVc = popover;
_popoverVc.delegate = self;
// popover的尺寸由其内的视图控制器决定。 // 设置穿透蒙板的Views
_popoverVc.passthroughViews = @[_segmentBtn]; // 要指向谁,rect传入谁的bounds
// inView是Rect的参考系
[popover presentPopoverFromRect:_menuBtn.bounds inView:_menuBtn permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }

注意其中的passthroughViews数组是指的能够穿过popoverView蒙板的views,因为popoverView显示时会有一个遮盖阻止用户与其他控件交互,在这个数组中的views可以穿过蒙板进行交互。

present方法传入的inView是popoverView位置的参考系,rect是显示的位置,一般有两种传递方法:①rect传入bounds而参考系为当前控件,②rect传入frame而参考系为父控件。

popoverView还有代理方法,用于阻止其dismiss或者监听销毁。

- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController{

    return YES;// 返回NO不能销毁

}
// 只有系统自己销毁才会调用,主动dismiss不会调用。
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{ NSLog(@"已经销毁"); }

第一个代理方法返回NO时不能销毁,利用这个方法可以做一些判断来决定能否销毁。

第二个代理方法在系统销毁popoverView时调用,如果自己dismiss是不会调用的。

(一〇六)iPad开发之UIPopoverController的使用的更多相关文章

  1. iOS iPad开发之UIPopoverController的使用

    1. 什么是UIPopoverController? 是iPad开发中常见的一种控制器(在iphone上不允许使用) 跟其他控制器不一样的是,它直接继承自NSObject,并非继承自UIViewCon ...

  2. (一〇七)iPad开发之modal的切换方式与展示方式

    在iPad上modal有四种切换方式,分别是竖直进入(由下到上,默认方式).水平翻转.淡入淡出. 属性要设置在将要modal出来的控制器上: /* typedef NS_ENUM(NSInteger, ...

  3. iOS开发之UIPopoverController

    1.概述 是iPad开发中常见的一种控制器(在iPhone上不允许使用),跟其他控制器不一样的是,它直接继承自NSObject,并非继承自UIViewController,它只占用部分屏幕空间来呈现信 ...

  4. 移动前端开发之viewport,devicePixelRatio的深入理解

    移动前端开发之viewport的深入理解 在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的met ...

  5. DarkStone - 跨平台移动应用开发之 Flex 的崛起

    我的好友Ds 发布一个flex的消息.我帮忙转发 DarkStone - 跨平台移动应用开发之 Flex 的崛起 (2013-08-20 22:28:32)     此文章由 周戈 (DarkSton ...

  6. ArcGIS Engine开发之旅04---ARCGIS接口详细说明

    原文:ArcGIS Engine开发之旅04---ARCGIS接口详细说明 ArcGIS接口详细说明... 1 1.      IField接口(esriGeoDatabase)... 2 2.    ...

  7. iOS-iPad开发之popoverController使用介绍

    iOS-iPad开发之popoverController使用介绍 iOS开发UI篇-popoverController使用注意 iOS SDK:自定义Popover(弹出窗口) 实现的简单例子: // ...

  8. iOS多线程开发之GCD(中篇)

    前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...

  9. Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)

    开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...

随机推荐

  1. [BZOJ]2594 水管局长数据加强版(Wc2006)

    失踪人口回归. LCT一直是小C的弱项,特别是这种维护链的信息的,写挂了就会调代码调到心态爆炸. 不过还好这一次的模板练习没有出现太多的意外. Description SC省MY市有着庞大的地下水管网 ...

  2. 基于Mapxtreme for JAVA的电子地图设计与实现

    基于Mapxtreme for JAVA的电子地图设计与实现学生毕业设计,适合测绘类专业研究目标:        开发一个基于MapXtreme for JAVA的校园电子地图项目,使用MapInfo ...

  3. Python3 运算符

    装载自:https://www.cnblogs.com/cisum/p/8064222.html Python3 运算符 什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 ...

  4. python 字典实现简单购物车

    # -*- coding: utf-8 -*-#总金额asset_all=0i1=input('请输入总资产:')asset_all=int(i1)#商品列表goods=[ {'name':'电脑', ...

  5. sql server 表分区

    背景: 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在不同的 ...

  6. P20 旅行助手,从未有过的至尊私人导游服务!

    旅行可以让人暂时抛掉生活中的琐事,工作上的压力,寻找内心的宁静.有的人是为了想多去见识不同的事物和人文风情,有的人是想去感受大自然的馈赠,看历史古迹感受古人智慧.歌德说过:人之所以爱旅行,不是为了抵达 ...

  7. bootmgr is missing 开机无法进系统怎么办

    认识 bootmgr: 启动管理器.Bootmgr是Boot Manager的缩写,是在Windows Vista和Windows 7中使用的新的启动管理器,以代替Windows xp中的启动管理器- ...

  8. java.lang.SecurityException: Prohibited package name:

    Prohibited package name:禁止使用的包名! 改个包名即可,全是这种bug多好啊.

  9. 关于npm run build 报错解决方案

    # 特定的错误 ERROR in statics/mobile/js/vendor.cef13a0e680a5bc0d8b3.js from UglifyJsUnexpected token: pun ...

  10. eclipse中创建完整的maven项目

    使用eclipse插件创建一个web project 首先创建一个Maven的Project如下图 我们勾选上Create a simple project (不使用骨架) 这里的Packing 选择 ...