iOS SDK:自定义Popover(弹出窗口)

移动开发 iOS
本文主要为各位介绍了iOS SDK的自定义Popover弹出窗口的学习内容,并且附带了源代码供大家学习之用,希望对大家有所帮助。

1.设置项目

Step 1

打开Xcode,选择File > New > Project,创建一个新项目,选择iOS Single View Application,再点击Next。

Step 2

填写一些列表格,项目名称、组织/公司名称以及公司标识符。在设备那个下拉菜单中选择iPad,在这一栏下边仅选择Automatic Reference Counting,点击Next。选择一个地点存放你的文件,点击创建。

2. 添加Navigation Controller

Step 1

添加Navigation Controller,这样就能添加一个按钮来展示popover。点击AppDelegate.m,找到 application:didFinishLaunchingWithOptions:方法。添加下述代码来创建一个 navigation controller,设置为root view controller。

  1. UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 
  2. self.window.rootViewController = navController; 

Step 2

在导航栏上添加一个“+”的按钮,然后打开ViewController.m文件,在[super viewDidLoad]下边把如下代码添加至viewDidLoad方法中。

  1. UIBarButtonItem *popoverButton = [[UIBarButtonItem alloc] 
  2. initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
  3.                     target:self 
  4.                     action:@selector(showPopover:)]; 
  5. self.navigationItem.rightBarButtonItem = popoverButton; 

UIBarButtonSystemItemAdd创建了一个“+”的按钮,我们将要把它添加至导航栏的右边,接下来我们会使用选择器执行showPopover:方法。 

3.展示Popover

Step 1

在执行showPopover:方法前先为popover controller添加一个属性,打开ViewController.h文件,添加如下属性:

  1. @property (nonatomic, strong) UIPopoverController *popController; 

Step 2

回到ViewController.m文件,在类扩展中声明showPopover:方法,如下:

  1. @interface ViewController () 
  2. - (void)showPopover:(id)sender; 
  3. @end 

Step 3

在@implementation下添加如下代码来定义这个方法:

  1. - (void)showPopover:(id)sender 
  2.    if (self.popController.popoverVisible) { 
  3.        [self.popController dismissPopoverAnimated:YES]; 
  4.        return
  5.    } 
  6.     UIViewController *contentViewController = [[UIViewController alloc] init]; 
  7.     contentViewController.view.backgroundColor = [UIColor yellowColor]; 
  8.     UIPopoverController *popController = [[UIPopoverController alloc] initWithContentViewController:contentViewController]; 
  9.     popController.popoverContentSize = CGSizeMake(300.0f, 600.0f); 
  10.     self.popController = popController; 
  11.     [self.popController presentPopoverFromBarButtonItem:sender 
  12. permittedArrowDirections:UIPopoverArrowDirectionUp 
  13.                                     animated:YES]; 

首先检查下popover能否展示在屏幕上。如果popover是可见的,那么会将popover隐藏起来,然后从该方法中直接return。如果 popover不可见,那么我们可以创建一个view controller,让它展示在popover中。然后创建 popover controller,并设置大小。

4. 测试标准的Popover

我们已经创建一个标准的Popover,创建运行你的项目,点击“+”按钮来展现一个基本的Popover。

5. 子类化UIPopoverBackgroundView

Step 1

为了自定义popover,我们需要子类化UIPopoverBackgroundView。点击 File > New > File, 选择iOS Cocoa Touch Objective-C Class, 点击Next.

Step 2

给class这一栏填上PopoverBackgroundView,从Subclass of下拉菜单中选择UIPopoverBackgroundView。

Step 3

这里有两个UIPopoverBackgroundView属性需要被覆盖,添加如下代码来定义arrow的方向和位移。

  1. @synthesize arrowDirection  = _arrowDirection; 
  2. @synthesize arrowOffset     = _arrowOffset; 

Step 4

这里有3个类方法需要覆盖,我们使用这个方法来定义一些值。

  1. #define kArrowBase 30.0f 
  2. #define kArrowHeight 20.0f 
  3. #define kBorderInset 8.0f 

Step 5

添加如下代码覆盖arrowBase, arrowHeight和contentViewInsets方法。

  1. + (CGFloat)arrowBase 
  2.     return kArrowBase; 
  3. + (CGFloat)arrowHeight 
  4.     return kArrowHeight; 
  5. + (UIEdgeInsets)contentViewInsets 
  6.     return UIEdgeInsetsMake(kBorderInset, kBorderInset, kBorderInset,       kBorderInset); 

arrowBase方法确定arrow底部的宽度,arrowHeight方法确定arrow的高度。

Step 6

添加背景色,在initWithFrame:方法的条件语句中添加如下代码:

  1. self.backgroundColor = [UIColor grayColor]; 

6.设置Popover Background View属性

测试popover之前,我们需要输入和设置popover controller的 popover Background View Class Property。打开ViewController.m文件,输入 popover background view头文件:

  1. #import "PopoverBackgroundView.h" 

还是在ViewController.m文件中,位于我们在showPopover:方法中创建UIPopoverController的下边,添加下边一行代码,

  1. popController.popoverBackgroundViewClass = [PopoverBackgroundView class]; 

7.测试Popover Background View

创建、运行项目,点击“+”的按钮来看下popover,可以看到标准的popover已经被取代。

8.设置阴影和圆角

wantsDefaultContentAppearance 方法决定是否在popover中展示默认的内置阴影和圆角,如果返回的是“NO”,Popover Background View将不再展示默认的阴影 和圆角,允许执行你自己的。添加如下代码来覆盖之前的方法:

  1. + (BOOL)wantsDefaultContentAppearance 
  2. return NO; 

9.添加Arrow

Step 1

我们需要创建和管理arrow,我们可以为image view声明一个属性,在类扩展中添加如下代码:

  1. @property (nonatomic, strong) UIImageView *arrowImageView; 

现在可以对image view进行实例化,使用如下代码替代initWithFrame:方法条件语句中的代码:

  1. self.backgroundColor = [UIColor clearColor]; 
  2. UIImageView *arrowImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 
  3. self.arrowImageView = arrowImageView; 
  4. [self addSubview:self.arrowImageView]; 

Step 2

通过使用以下代码来更新在PopoverBackgroundView.m定义的kBorderInset来改变border inset:

 

  1. #define kBorderInset 0.0f 

Step 3

为了画这个arrow,我们需要声明一个方法来展现,可以在PopoverBackgroundView.m类扩展中添加下边这个方法声明:

  1. - (UIImage *)drawArrowImage:(CGSize)size; 

Step 4

在@implementation下添加方法定义:

  1. - (UIImage *)drawArrowImage:(CGSize)size 
  2.     UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
  3.     CGContextRef ctx = UIGraphicsGetCurrentContext(); 
  4.     [[UIColor clearColor] setFill]; 
  5.     CGContextFillRect(ctx, CGRectMake(0.0f, 0.0f, size.width, size.height)); 
  6.     CGMutablePathRef arrowPath = CGPathCreateMutable(); 
  7.     CGPathMoveToPoint(arrowPath, NULL, (size.width/2.0f), 0.0f); 
  8.     CGPathAddLineToPoint(arrowPath, NULL, size.width, size.height); 
  9.     CGPathAddLineToPoint(arrowPath, NULL, 0.0f, size.height); 
  10.     CGPathCloseSubpath(arrowPath); 
  11.     CGContextAddPath(ctx, arrowPath); 
  12.     CGPathRelease(arrowPath); 
  13.     UIColor *fillColor = [UIColor yellowColor]; 
  14.    CGContextSetFillColorWithColor(ctx, fillColor.CGColor); 
  15.     CGContextDrawPath(ctx, kCGPathFill); 
  16.     UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
  17.     UIGraphicsEndImageContext(); 
  18.     return image; 

不用输入图片,上述代码可以自动生成一个arrow。

Step 5

每次popover的background view的子类的bounds 改变时,这个arrow的frame需要重新计算。我们可以通过覆盖layoutSubviews来达到目的,为layoutSubviews添加如下代码:

  1. - (void)layoutSubviews 
  2.     [super layoutSubviews]; 
  3.     CGSize arrowSize = CGSizeMake([[self class] arrowBase], [[self class] arrowHeight]); 
  4.     self.arrowImageView.image = [self drawArrowImage:arrowSize]; 
  5.     self.arrowImageView.frame = CGRectMake(((self.bounds.size.width - arrowSize.width) kBorderInset), 0.0f, arrowSize.width, arrowSize.height); 

10. 测试Popover

源文件:

http://down.51cto.com/data/816045

责任编辑:闫佳明 来源: cocoachina
相关推荐

2013-06-27 11:10:01

iOS开发自定义UISlider

2009-12-24 15:22:10

WPF继承自定义窗口

2013-07-18 16:09:10

自定义iOS状态栏iOS开发iOS学习

2011-08-02 11:17:13

iOS开发 View

2021-01-20 08:58:39

iOS 14桌面图标快捷指令

2012-06-01 11:02:33

2017-10-25 14:07:54

APPiOSxcode

2012-12-24 14:42:48

iOS自定义状态栏

2015-02-12 15:33:43

微信SDK

2011-08-18 09:44:33

iPhone SDK仪表控件UIDialView

2009-10-30 08:47:57

Windows 7窗口排列

2015-01-15 16:45:05

iOS源码自定义画图

2015-02-12 15:38:26

微信SDK

2016-12-26 15:25:59

Android自定义View

2015-10-12 16:47:13

iOS下拉线条动画

2016-04-06 11:14:48

iOS相机自定义

2016-11-16 21:55:55

源码分析自定义view androi

2011-06-23 10:49:13

Qt 自定义信号

2021-11-23 15:06:42

Kubernetes 运维开源

2011-12-16 14:23:51

Java
点赞
收藏

51CTO技术栈公众号