`
啸笑天
  • 浏览: 3465561 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

UIPopoverController 使用总结

 
阅读更多

 

先看他的继承关系,UIPopoverController是直接继承自NSObject,它和UIViewController没有关系.那它是怎么实现弹出在所有View之上的,我猜测是利用了keywindow,把这个View加在keywindow里面,我做了个试验,一般我们会在AppDelegatedidFinishLaunchingWithOptions中来初始化我们的window,把应用的第一个viewcontroller加到window中去,并在最后调用windowmakekeyandvisible方法。于是我尝试在window实例调用makekeyandvisible方法的之前弹出一个UIPopoverController,于是得到了下面的错误:

***Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:'-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.'

 

所以我猜UIPopoverController就是把你提供的Viewcontroller包起来加一个arrow框和背景,加到keywindow中去。另外如果你在显示地时候传入的BarButtonItemnil,也会报这个错误,但实际上和window无关。

使用注意:

一、.UIPopoverController该控制器的内容必须由一个控制器提供;提供方式有3个:

1

- (id)initWithContentViewController:(UIViewController *)viewController

//很简单的初始化方法,把你要展示的Viewcontroller传给它。

2

-(void)setContentViewController:(UIViewController*)viewController animated:(BOOL)animated

//可以在UIPopoverController还在显示的时候动态地更换ContentViewController

3

@property (nonatomic, retain) UIViewController *contentViewController

 

二、设置内容大小:
/* This property allows direction manipulation of the content size of the popover. Changing the property directly is equivalent to animated=YES. The content size is limited to a minimum width of 320 and a maximum width of 600. */ @property (nonatomic) CGSize popoverContentSize; - (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated;

 

/* contentSizeForViewInPopover allows you to set the size of the content from within the view controller. This property is read/write, and you should generally not override it. */ @property (nonatomic,readwrite) CGSize contentSizeForViewInPopover NS_AVAILABLE_IOS(3_2);

 

.设置箭头方向:
@property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection

 

typedef NS_OPTIONS(NSUInteger, UIPopoverArrowDirection) {

    UIPopoverArrowDirectionUp = 1UL << 0,

    UIPopoverArrowDirectionDown = 1UL << 1,

    UIPopoverArrowDirectionLeft = 1UL << 2,

    UIPopoverArrowDirectionRight = 1UL << 3,

    UIPopoverArrowDirectionAny = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown | UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight,

    UIPopoverArrowDirectionUnknown = NSUIntegerMax

};

 

四、

1、如果从一个导航按钮处呈现,使用:
presentPopoverFromBarButtonItem:permittedArrowDirections:animated:

这种方式弹出的popVC接近于模态, 但不完全是模态, 因为NavigationBar上的所有按钮都高于这个popVC层, 也就是说NavigationBar上的按钮可以继续响应用户的操作,而不管当前是否有从BarButtonItem弹出的popVC

这样就有可能引发一些问题, 如, 我们再次点击这个BarButtonItem时, 则又会执行一次弹出操作, 实际上界面上将会有两个popOver 更明显的问题是, 如果我们点navigationBar上的返回按钮,把当前这个界面pop出去, 则会因为当前还有展示的popVC而使当前界面崩溃。

一般实现:

- (IBAction)languageButtonTapped {

    if (self.languagePopoverController == nil) {

        BIDLanguageListController *languageListController =

        [[BIDLanguageListController alloc] init];

        languageListController.detailViewController = self;

        UIPopoverController *poc = [[UIPopoverController alloc]

                                    initWithContentViewController:languageListController];

        [poc presentPopoverFromBarButtonItem:languageButton

                    permittedArrowDirections:UIPopoverArrowDirectionAny

                                    animated:YES];

        self.languagePopoverController = poc;

    } else {

        if (languagePopoverController != nil) {

            [languagePopoverController dismissPopoverAnimated:YES];

            self.languagePopoverController = nil;

        }

    }

}


2
、如果要从一个视图出呈现,使用:
presentPopoverFromRect:inView:permittedArrowDirections:animated:

这个方法需要传入一个CGRect和一个View,而只有这个CGRect的值是相对于这个View的,这个Arrow才能指到正确的位置。我猜测它是在视图树中向上搜索把它转化为在keywindow中的值再显示。举个例子,如果你要箭头指向被点击的这个button

那么一种方法是:

[xxx presentPopoverFromRect:button.bounds inView:button permittedArrowDirections:xx animated:YES];

一种方法是转换为他的父视图中的CGRect

[xxx presentPopoverFromRect:button.frame inView:button.superview permittedArrowDirections:xx animated:YES];

 // inView的中心点是用来画箭头的,如果中心点如果出了屏幕,系统会优化到窗口边缘

//inView是个CGRectMake(x0, y0, x1, y1),如果你想绝对定位的话,可以把x1,y1设置为0x0,y0就是箭头的位置。

这种方式弹出的popVC就是绝对的模态了, 不把这个popVC消隐, 其它任何地方, 包括NavigtionBar都得到不交互。

注意:如果设备旋转以后,位置定位错误需要在父视图控制器的下面方法里面重新定位:
didRotateFromInterfaceOrientation:
(在这个方法体里面重新设置rect
然后再次调用:
- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated

 

五、UIPopoverController的外观

通过popoverBackgroundViewClass属性和popoverLayoutMargins,你就可以自己定制Popover的外观了,popoverLayoutMargins是指你的popover相对于整个window上下左右的margin,当你设置的值大于它目前的值的时候,它才会调整(也就是让它自己更小的margin才会被实现).另外通过subclass UIPopoverBackgroundView,并把该class指定给popoverBackgroundViewClass属性,你就可以随意改变他的外观了。

 

六、UIPopoverController防止点击区域外消失

UIPopoverController的默认行为是,当你点击UIPopoverController以外的区域时,它会消失,改变这种行为就要利用属性passthroughViews.它的意思是,UIPopoverController点击在它的区域外,如果点到了passthroughViews中的View的时候,是不会消失的。我写了demo试了一下,passthroughView中被点击的View以及其SubView都不会让UIPopoverController消失。

一般点击区域外消失实现代理来处理后续动作:

- (void)popoverControllerDidDismissPopover:(UIPopoverController*)popoverController{
      if (popover) {
          [popover dismissPopoverAnimated:YES];
          [popover release];
          popover=nil;
          if (popoverContent != nil) {
              [popoverContent release];
              popoverContent = nil;
          }
      }
  }

 

七、UIPopoverController的内存管理

根据目前我使用的情况来看,我常用的使用方式是在属性中声明一个 retain UIPopoverController,然后在创建的时候指向创建的临时变量,然后释放临时变量.我还没有发现更方便的内存管理的方法,UIPopoverControllerUIActionSheet有点不一样,你必须自己来retain这个UIPopoverController,如果在UIPopoverController还没有dismiss的时候你就release掉了,就会出错。当然,你可以把UIPopoverControllerdelegate设为self,然后在popoverControllerDidDismissPopover中释放他,但我感觉这样还不如采用属性更方便,因为你没法代码控制popover的消失了,总得维护一个引用,当然,象我这种方法得话,你很多时候是在延迟释放这个popOver了。一般来说,你可以经常使用这样得代码:

[self.pop dismissPopoverAnimate:xx];

self.pop=nil;

因为给nil发送一个dismissxx是没有问题的,然后再释放,这样可以保证内存不混出错。当然,如果实在不放心,可以总是在前面加一个if(!=nil)的判断。

 

七、

多个UIPopoverController的切换问题

情况描述:多个button控制对应的UIPopoverController,当一个UIpopverController_A打开的时候,点击button_B去打开另外一个UIPopverContrller_B,每次都需要点击两下才能打开,(我的理解)第一次只是关闭UIpopverController_A,第二次才是打开UIPopverContrller_B

解决方法:

UIPopoverController * poper...
UIButton * BtnA...
NSArray *array=[NSArray arrayWithObjects:BtnA,BtnB,BtnC,BtnD,BtnE,BtnF,BtnG,BtnH];
poper.passthroughViews=array;
设置passthroughViews为这个数组就可以了

 

 

分享到:
评论

相关推荐

    iOS弹出框总结代码

    主要是对UIPopoverController、UIPopoverPresentationController、UIAlertView、UIActionSheet、UIAlertController的使用总结代码。

    IOS 开发总结

    - 特殊视图和控件的使用:例如UIPopoverController、UIColor、手势识别器等。 - App Store集成:介绍了如何引导用户进入应用商店页面。 - 呈现和动画效果:解释了如何实现视图的淡入淡出、CALayer和CGLayer高清...

    iOS开发总结

    关于UI方面,还有一些高级功能,如使用CALayer和CGLayer实现高清显示,通过UIPopoverController来展示弹出式窗口,使用block来实现简单的动画效果,以及如何隐藏app图标上的发光效果。此外,还可以通过编写手势识别...

    ios-cell点击下拉.zip

    3. **使用UIPopoverController或UIActionSheet**:如果下拉内容较多,可以使用弹出视图来展示。但这两种控件在iPad上更常见,iPhone上通常不推荐使用。 4. **使用UICollectionView或UIStackView**:在cell内部嵌入...

    iOS 弹出视图

    3. UIPopoverController:适用于iPad应用,用于在大屏幕设备上显示全尺寸视图。 二、自定义弹出视图 对于更复杂的弹出视图需求,开发者通常会自定义视图。以下是一些常见的实现方式: 1. UIView动画:通过修改...

    Beginning iOS 5 Development

    - **UIPickerView与UIPopoverController**:UIPickerView是一个可以滚动选择项目的视图,UIPopoverController则用于显示弹出窗口。 ### 2. JSON在iOS开发中的作用 - **JSON简介**:JSON是一种轻量级的数据交换格式...

    iOS9 系统分享调用之UIActivityViewController

    总结来说,UIActivityViewController在iOS9中的使用主要包括以下几点: 1. 创建UIActivityViewController实例并传入要分享的内容。 2. 如果在iPad上展示,需使用UIPopoverPresentationController,并设置sourceView...

    JWPopover:Popover或PopupView。易于使用于popover或popup

    在iOS应用开发中,Popover和PopupView经常被用于展示临时信息或者提供附加操作选项,它们在用户界面上呈现为一种半透明的浮层,通常与iPad应用中的UIPopoverController类似。`JWPopover`是一个Objective-C编写的开源...

    iOS 下拉框,可自动识别向上向下展开

    在iOS开发中,通常我们会用到系统的UIPickerView或UIPopoverController来实现类似的功能,但这些组件可能无法满足所有需求,比如自定义样式、动画效果等。因此,开发者经常需要封装自己的控件来达到特定的设计需求。...

    右下角点击弹出菜单

    在移动应用开发中,Android可以使用`PopupMenu`或自定义View,iOS则可以利用`UIPopoverController`(对于iPad)或自定义视图控制器来实现。 8. 可访问性考虑:设计弹出菜单时,也要考虑到不同用户的需求,包括视力...

    WHC_ComboBoxDemo

    总结来说,"WHC_ComboBoxDemo"是一个展示了如何在iOS中自定义下拉按钮控件的实例,涵盖了自定义控件、图标和文字的设置、下拉功能的实现、MVC架构、布局管理等多个关键知识点。通过研究这个项目,开发者可以学习到...

    ios pickerView

    `UIPickerView`常与其他UI组件一起使用,如`UITextField`或`UIPopoverController`。在`UITextField`中,`UIPickerView`可以作为输入辅助视图,让用户在输入框内选择值。 ### 8. 性能优化 在处理大量数据时,注意...

    IOS弹出菜单源码

    FPopover是一个流行的开源库,用于在iOS应用中实现类似iPad上的UIPopoverController的效果。修改后的FPopover添加了对导航条(UINavigationController)的支持。在iOS开发中,导航条是用于在多个视图控制器之间导航...

    iOS实现圆角箭头矩形的提示框

    在iPad上,我们可以直接使用UIPopoverController类来实现,但在iPhone上则需要自定义视图来达到相同效果。本篇文章将探讨如何在iOS中自定义一个圆角箭头矩形的提示框。 首先,我们要了解CGContextRef。CGContextRef...

Global site tag (gtag.js) - Google Analytics