您的位置:首页 > 大数据 > 人工智能

Xcode4.2下iPhone多视图开发(自已创建MainWindow.xib和不用MainWindow.xib两种实现)

2013-08-09 11:46 579 查看
使用Xcode4以前的版本进行iPhone开发,新建Window-based Application类型的工程时,都会自动生成MainWindow.xib,并且都至少包含一个UIApplicationDelegate和一个UIWindow对象。

但是Xcode4以后,新建工程时,工程template这一块有很大改动,没有Window-based Application这一项了,但是有个Empty Application(iOS->Application下),现在描述以这种方式新建工程,然后自已创建MainWindow.xib并使用,和不用MainWindow.xib两种实现。

另外多视图实现采用三个UIViewController来实现,一个FirstViewController使用FirstView.xib设计界面,上面一个按钮点后切找到SecondViewController的界面,一个SecondViewController使用SecondView.xib设计界面,上面也有一个按钮点后切换到FirstViewController,一个SwitchViewController负责这两个controller的界面的切换,SwitchViewController作为rootViewController,如果一个应用没有rootViewController启动就会报错“Applications
are expected to have a root view controller at the end of application launch”,其实上面两种方式就是:

第一种:创建MainWindow.xib,默认有window,需要手动添加delegate指定所属类为MVTestAppDelegate,添加UIViewController,指定所属类为SwitchViewController,然后在委托MVTestAppDelegate代码中[windowaddSubview:viewController.view];将该controller的view添加到window。不需要再使用代码来创建和初始化应用委托的window和controller的view了,这些都通过MainWindow.xib来做了。下面第二种方式就是这部分不通过MainWindow.xib来做,而是通过代码实现就用delegate的window和controller的创建和初始化

第二种:即上面第一种方式中MainWindow.xib实现的工作通过Delegate中代码来实现。详细如下:

CMD+SHIFT+N打开新建工程窗口,选择Empty Application这一项(会默认提供一个delegate和一个window),取名为MVTest。如下图:





新建SwitchViewController继承UIViewController,去掉with XIB for user interface,

同SwitchViewController一样,新建FirstViewController,和SecondViewController,然后新建FirstView.xib和Second.xib,如下图:



两个xib上面分别都添加一个label和一个button,如下图:



接下来在MVTestAppDelegate头文件中添加:

@property (nonatomic, retain)SwitchViewController *viewController;// 注意:window和viewController前面的IBOutlet

+(MVTestAppDelegate *)App;

并且在*.m文件中实现,如下图:





另外,SwitchViewController.h:

#import <UIKit/UIKit.h>

@classFirstViewController;

@classSecondViewController;

@interface SwitchViewController :UIViewController {

FirstViewController* firstviewcontroller;

SecondViewController* secondviewcontroller;

}

@property (nonatomic,retain)FirstViewController* firstviewcontroller;

@property (nonatomic,retain)SecondViewController* secondviewcontroller;

-(void)initView;

-(void)showFirstView;

-(void)showSecondView;

-(void)removeAllView;

@end

SwitchViewController.m:

#import "SwitchViewController.h"

#import "FirstViewController.h"

#import "SecondViewController.h"

@implementation SwitchViewController

@synthesize firstviewcontroller;

@synthesize secondviewcontroller;

-(void)initView{

NSLog(@"ttt");

if(self.firstviewcontroller ==nil){

self.firstviewcontroller = [[FirstViewControlleralloc]initWithNibName:@"FirstView"bundle:nil];

}

[selfremoveAllView];

[self.viewinsertSubview:self.firstviewcontroller.viewatIndex:0];

}

-(void)showFirstView{

if(self.firstviewcontroller ==nil){

self.firstviewcontroller = [[FirstViewControlleralloc]initWithNibName:@"FirstView"bundle:nil];

}

[selfremoveAllView];

[self.viewinsertSubview:self.firstviewcontroller.viewatIndex:0];

}

-(void)showSecondView{

if(self.secondviewcontroller ==nil){

self.secondviewcontroller = [[SecondViewControlleralloc]initWithNibName:@"SecondView"bundle:nil];

}

[selfremoveAllView];

[self.viewinsertSubview:self.secondviewcontroller.viewatIndex:0];

}

-(void)removeAllView{

for(NSInteger i=0;i<[self.view.subviewscount];i++){

[[self.view.subviewsobjectAtIndex:i]removeFromSuperview];

}

}

@end


在这两个controller,FirstViewController和SecondViewController里面,均分别添加-(IBAction)buttonClick:(id)sender;,并实现:

-(IBAction)buttonClick:(id)sender{

[[MVTestAppDelegateApp].viewControllershowSecondView]; //FirstViewController调用这个showSecondView,SecondViewController里面调用showFirstView.

}

然后分别指定FirstView.xib的File's Owner所属类为FirstViewController,SecondView.xib的所属类为SecondViewController,并将xib界面上的按钮与IBAction连接,同时将Outlets下面的view与界面的view连接。如下图:





接下来涉及到MainWindow.xib了:

一、不用MainWindow.xib

(1) 初始化delegate的window.

self.window = [[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]]autorelease];

(2) 指定delegate所在window的rootViewController,即SwitchViewController,需要新建并初始化.

self.viewController = [[[SwitchViewControlleralloc]init]autorelease];

[self.viewControllerinitView];

self.window.rootViewController =self.viewController;

如下图:



二、自已创建MainWindow.xib并使用

新建一个window类型的xib命名为MainWindow.xib。如下图:



,新建好后,从Library中拖一个Object到界面上,指定其所属类为MVTestAppDelegate,



然后拖一个View Controller到界面上,并且指定所属类为SwitchViewController。

指定MainWindow.xib的File's Owner的所属类为UIApplication,并将其delegate与MVTestAppDelegate相连接:



接下来选中Test App Delegate,即MVTestAppDelegate,将viewController与界面上的Switch View Controller相连,window与window相连,





至此连完后,有个很重要的地方需要设置一下,那就是Info.plist,因为MainWindow.xib是自已创建的,所以需要指定NSMainNibFile为MainWindow。



然后运行一下,发现不行,会报错“Applications are expected to have a root view controller at the end of application launch”,那是因为没有在delegate启动时将rootViewController的view添加到delegate 的window中。虽然rootViewController(即MainWindow.xib中的Switch View Controller)已经在MainWindow.xib中指定并初始化了,但是并没有明确将该ViewController的view添加进来。另外还需要注意的一点是delegate的window已经在MainWindow.xib中初始化了。所以也不需要再通过

self.window = [[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]]autorelease];

来初始化了,此条不再需要,否则会发现rootViewController 的view被该新建的白色window挡住了,点back键可以看到退出动画时rootViewController 的view瞬间闪现。

即:

(1) 去掉delegate的window初始化过程:

//self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

(2) 添加rootViewController的view到delegate的window:

// 应用的rootViewController虽然已经在MainWindow.xib中定义并初始化了,但是还需要将之加到delegate的window上

[self.viewControllerinitView];

[self.windowaddSubview:self.viewController.view];

如下图:



附:最终运行效果,即刚启动显示FirstViewController的view,点击Show Second,切换到SecondViewController的view,点上面的Show First 则切换回来,如下图:





总结:

不使用MainWindow.xib时,需要通过代码实现delegate的window的初始化,同时还需要初始化一个ViewController并且指定为 delegate的window的rootViewController.

使用MainWindow.xib时,Xcode4及以后的版本需要自已创建,并且添加delegate和rootViewController,同时注意File's Owner(所属类UIApplication)的delegate与添加的delegate连接,以及指定添加的Delegate的window和viewController与界面上window和添加的具体viewController连接。同时还需要在info.plist中指定NSMainNibFile键值。最后在delegate的启动完成接口中将MainWindow.xib中的rootViewController的view添加到delegate的window,并且去掉delegate的window的默认初始化过程.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

(补充):

(1)没有MainWindow.xib时,需要指定应用Delegate的self.window和self.window.rootViewController,window和rootViewController都需要自已来定义、分配空间、初始化,在没有使用ARC的情况下,还需要控制内存回收。

(2)有MainWindow.xib时,并且在info.plist中指定了NSMainNibFile键值为MainWindow,则默认delegate的window即为MainWindow.xib中的window已经被定义和初始化了,内存回收什么的都不用我们管,并且在MainWindow.xib中若指定有UIViewController,则这个UIViewController也是定义并初始化了同window一样不用我们来管理内存回收。即,我们直接用里面的window和UIViewController即可。唯一需要注意的就是:MainWindow.xib中的UIViewController虽然不再需要我们来定义并初始化,但是这个UIViewController还没有被添加到self.window,所以我们唯一需要做的就是将这个UIViewController的view添加到self.window,或者使用这个UIViewController来初始化一个UINavigationController,然后将这个UINavigationController的view添加到self.window即可。

注:MainWindow.xib中不一定非得添加和指定View Controller,若在MainWindow.xib中添加了使用时也不一定就非得作为rootViewController,来添加到self.window,换句话说就是也可以做为rootViewController的子view controller被添加,只是在MainWindow.xib中添加了它的话使用它时不需要定义和初始化罢了(前提是需要在应用delegate头文件里面添加该viewController的IBOutlet,并且在MainWindow.xib界面中选中该delegate,然后将这个delegate中刚添加的IBOutlet与界面上的viewController相关联即可)。若没有在MainWindow.xib中添加那在存在xViewController.h、xViewController.m、xViewController.xib的情况下,使用前使用alloc
init autorelease(若使用的地方没有retain则不要使用autorelease)进行一下定义和初始化并适当控制内存回收即可.

(注:后来发现self.window.rootViewController = self.myNavController ;和[self.window addSubview:self.myNavController.view];二者等价.)

通过这些可以猜想也可以在MainWindow.xib中添加多个view controller,然后在应用delegate里面添加对应view controller 的 IBOutlet,并且在MainWindow.xib中选中这个应用delegate将其添加的IBOutlet与界面上的view controller对应关联,然后就可以在应用delegate里面直接用这些在MainWindow.xib中添加的view controller了,不再需要关心空间分配、初始化及内存回收管理等工作。

另外,新建UIViewController的时候,可以选中With XIB for user interface,那么这个UIViewController的界面可以直接在对应的xib文件中通过Interface Builder进行设计,也可以直接在对应*.m中的viewDidLoad中进行代码设计。具体在xib中设计,又想在代码中关联并使用那就是添加IBOutlet和IBAction进行拖拽连接的问题了,前面“iPhone开发学习笔记001——Xib界面上的控件与代码的相互关联方法”中有介绍.

转载地址:http://www.2cto.com/kf/201202/120864.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐