iPhone开发学习笔记004——自定义背景透明非全屏弹出窗口,子类化UIWindow
![](http://hi.csdn.net/attachment/201202/14/0_13292264517R79.gif)
![](http://hi.csdn.net/attachment/201202/14/0_1329226463GA86.gif)
下面说说具体过程。
一、新建一个single view application工程,并且添加相关的控件并拖拽连接:
如下图:
![](http://hi.csdn.net/attachment/201202/14/0_132922667628L0.gif)
![](http://hi.csdn.net/attachment/201202/14/0_13292266949BBW.gif)
新建一个OC类,继承自UIWindow,如下图:
![](http://hi.csdn.net/attachment/201202/14/0_1329227201Nnp3.gif)
![](http://hi.csdn.net/attachment/201202/14/0_1329227187LFiO.gif)
CustomWindow.h:
#import <UIKit/UIKit.h>
@interface CustomWindow :UIWindow {
UIView *superView;
UIView *backgroundView;
UIImageView *backgroundImage;
UIView *contentView;
BOOL closed;
}
@property (nonatomic,retain)UIView *superView;
@property (nonatomic,retain)UIView *backgroundView;
@property (nonatomic,retain)UIImageView *backgroundImage;
@property (nonatomic,retain)UIView *contentView;
-(CustomWindow *)initWithView:(UIView *)aView;
-(void)show;
-(void)close;
@end
CustomWindow.m:
#import "CustomWindow.h"
@implementation CustomWindow
@synthesize superView;
@synthesize backgroundView;
@synthesize backgroundImage;
@synthesize contentView;
-(UIImage *) pngWithPath:(NSString *)path
{
NSString *fileLocation = [[NSBundlemainBundle]pathForResource:pathofType:@"png"];
NSData *imageData = [NSDatadataWithContentsOfFile:fileLocation];
UIImage *img=[UIImageimageWithData:imageData];
return img;
}
-(CustomWindow *)initWithView:(UIView *)aView
{
if (self=[superinit]) {
//内容view
self.contentView = aView;
//初始化主屏幕
[selfsetFrame:[[UIScreenmainScreen]bounds]];
self.windowLevel =UIWindowLevelStatusBar;
self.backgroundColor = [UIColorcolorWithRed:0green:0blue:0alpha:0.1];
//添加根view,并且将背景设为透明.
UIView *rv = [[UIViewalloc]initWithFrame:[selfbounds]];
self.superView = rv;
[superViewsetAlpha:0.0f];
[self addSubview:superView];
[rv release];
//设置background view.
CGFloat offset = -6.0f;
UIView *bv = [[UIViewalloc]initWithFrame:CGRectInset(CGRectMake(0,0,self.contentView.bounds.size.width,self.contentView.bounds.size.height), offset, offset)];
self.backgroundView = bv;
[bv release];
//用圆角png图片设为弹出窗口背景.
UIImageView *bi = [[UIImageViewalloc]initWithImage:[[selfpngWithPath:@"alert_window_bg"]stretchableImageWithLeftCapWidth:13.0topCapHeight:9.0]];
self.backgroundImage = bi;
[backgroundImagesetFrame:[backgroundViewbounds]];
[backgroundViewinsertSubview:backgroundImageatIndex:0];
[backgroundViewsetCenter:CGPointMake(superView.bounds.size.width/2,superView.bounds.size.height/2)];
[superViewaddSubview:backgroundView];
CGRect frame =CGRectInset([backgroundViewbounds], -1 * offset, -1 * offset);
//显示内容view
[backgroundViewaddSubview:self.contentView];
[self.contentViewsetFrame:frame];
closed =NO;
}
returnself;
}
//显示弹出窗口
-(void)show
{
[selfmakeKeyAndVisible];
[superView setAlpha:1.0f];
}
-(void)dialogIsRemoved
{
closed = YES;
[contentViewremoveFromSuperview];
contentView =nil;
[backgroundViewremoveFromSuperview];
backgroundView =nil;
[superViewremoveFromSuperview];
superView =nil;
[self setAlpha:0.0f];
[selfremoveFromSuperview];
self = nil;
// NSLog(@"===> %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
}
-(void)close
{
[UIViewsetAnimationDidStopSelector:@selector(dialogIsRemoved)];
[superView setAlpha:0.0f];
// NSLog(@"===> %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
}
接下来,在CustomAlertWindowViewController中添加该自定义CustomWindow对象成员,并添加一个button属性与XIB界面上的Press Me!按钮相连接,如下图:![](http://hi.csdn.net/attachment/201202/14/0_1329227748SZW7.gif)
至此,CMD+R运行一下,是第一张图的效果,占击按钮没有反应,那是因为我们没有为该按钮添加相应的行为,接下来我们实现点击按钮弹出一个窗口,该窗口即由CustomAlertWindowViewController中的自定义窗口customWindow来呈现。看customWindow中的代码,需要添加一张圆角PNG图片做为背景,该PNG图片不一定要和该内容视图contentView大小一模一样,只需要四个角是圆角,中间是纯色即可,使用到一个经常用的函数CG_EXTERNCGRect CGRectInset(CGRect rect,CGFloat dx,CGFloat dy),该方法可以实现四个角落不变,中间拉抻,具体该函数的解释请参考APPLE的官方文档,不多解释!将alert_window_bg.png添加至工程的Supporting Files下即可。
好了,废话不多说,下面新建一个view这个view我们用一个xib来实现,即ContentView.xib,依次如下图:
![](http://hi.csdn.net/attachment/201202/14/0_1329228791OW25.gif)
![](http://hi.csdn.net/attachment/201202/14/0_1329228805848E.gif)
其它的不用注意什么,需要注意的一点是ContentView.xib的根view的background需要设为clear color,即透明。下面,我们要在CustomAlertWindowViewController中用到这个,将该xib中的view做参数初始化为customWindow的contentView,首先需要动态加载一下xib文件,具体使用的代码如下:
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[buttonaddTarget:selfaction:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonAction:(id)sender {
NSLog (@"+++ doAction executing. +++");
NSArray *nib = [[NSBundlemainBundle]loadNibNamed:@"ContentView"owner:selfoptions:nil];
UIView *tmpContentView = [nibobjectAtIndex:0];
UIButton *tmpButton = (UIButton *)[tmpContentViewviewWithTag:2];
[tmpButton addTarget:selfaction:@selector(okAction:)forControlEvents:UIControlEventTouchUpInside];
customWindow = [[CustomWindowalloc]initWithView:tmpContentView]; //将刚加载进来的xib中的view作为参数传递给CustomWindow的contentView。
[customWindowshow];
}
- (void)okAction:(id)sender{
NSLog (@"+++ okAction executing. +++");
[customWindowclose];
customWindow.hidden =true;
}
最后运行一下,效果即为第二张图的样子。
因为时间的原因,介绍的不太详细,但是关键点都介绍到了,里面最核心的就是CustomWindow的实现,这里只是做为以后自我参考,留个记录,搞应用开发和搞底层开发一个很大的不同就是搞应用的知识点很多,很零碎,需要不断的积累,怕忘记,所以这里记录一下!