您的位置:首页 > 移动开发 > IOS开发

iOS 实现简单的界面切换

2014-12-16 11:27 267 查看
以下是在iOS中最简单的界面切换示例。使用了多个Controller,并演示Controller之间在切换界面时的代码处理。

实现的应用界面:







首先,创建一个window-based application,即:





使用window-base application的目的是,尽量从最基本的情况下说明程序的编写过程。项目创建好后,即可以编译运行,执行结果是白屏页面:





编写第一个视图和控制器,我管它叫Topic,即主题,因此控制器命名为:TopicController,视图TopicView。

创建TopicController:





这样将创建3个文件:





视图xib文件也一同创建了。而且:





会自动生成File’s Owner的Class。

在MainWindow.xib中,将刚刚创建的控制器(TopicController)加进来。

先要拖拽一个View Controller进来:





然后,给View Controller改名:





下面,要把这个Controller设置给WindowDemoAppDelegate。在它的头文件中:


#import <UIKit/UIKit.h>

#import "TopicController.h"

@interface WindowDemoAppDelegate : NSObject
<UIApplicationDelegate> {

UIWindow
*window;

IBOutlet
TopicController *topicController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end


在实现文件中:


#import "WindowDemoAppDelegate.h"

@implementation WindowDemoAppDelegate

@synthesize window;

#pragma mark –

#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

// Override
point for customization after application launch.

[self.window
addSubview:topicController.view];


[self.window
makeKeyAndVisible];

return
YES;

}


然后,为了看的清楚,把TopicController.xib文件中的视图颜色改为绿色:



运行应用,会看到如下效果:



为该界面添加一个按钮:



为该按钮创建处理方法。在TopicController的头文件中:


#import <UIKit/UIKit.h>

@interface TopicController : UIViewController {

}

-(IBAction) getDetail:(id)sender;

@end


在实现文件中:


#import "TopicController.h"

@implementation TopicController

-(IBAction) getDetail:(id)sender{

NSLog(@"get
detail …");

}



在IB中,将按钮和控制器的Action连接:



再次运行应用,可看到日志中的打印内容:



按照上面创建Controller的方法,再创建一个DetailController。先把DetailController.xib的视图设置颜色,为了以后调试观察识别。



然后,我需要点击TopicController视图中按钮切换到DetailController视图。这需要在下面代码中想办法:


#import "TopicController.h"

@implementation TopicController

-(IBAction) getDetail:(id)sender{

NSLog(@"get
detail …");

}




基本思路是找到window实例,可通过window的rootViewController属性设置新的控制器实例(比如DetailController),取代TopicController。代码可这样写:


#import "TopicController.h"

#import "DetailController.h"

@implementation TopicController

-(IBAction) getDetail:(id)sender{

NSLog(@"get
detail …, window.views: %@",self.view.window.subviews);

DetailController *detailController=[[DetailController alloc]
initWithNibName:@"DetailController" bundle:nil];

self.view.window.rootViewController=detailController;

NSLog(@"window.views:
%@",detailController.view.window.subviews);

}


加上这部分代码后,点击按钮就可生效,产生这样的效果:






上面的代码做一下解释:

首先创建了一个新的DetailController实例

然后,当前的controller的view属性,可以获得window实例,通过window实例的rootViewController属性的设置,将当前的控制器替换为新的控制器

window对象是一个非常重要的类,你可以把它看作ios开发的画框,视图是放在画框里的,window有个subvews列表,里面可以存放多个View

当设置window.rootViewController属性的时候,window会自动将该属性的UIViewController的view添加到window的subview中,这也是为什么日志中打印的window.subviews列表中有两个实例的原因

这个代码很不完备,比如存在内存泄漏,需要这样:


DetailController *detailController=[[[DetailController alloc]
initWithNibName:@"DetailController" bundle:nil]
autorelease];



因为,这个detailController这句话后,计数器为1了,再赋值给window.rootViewController属性,就是2了。因此这里要做自动释放。

这个代码还有个问题,就是看上去很别扭,在一个控制器代码里去创建另一个控制器。这一方面很容易出问题,另一方面,代码的结构不清晰。下面用委托模式给代码解耦,也为下一步做返回按钮做准备。

委托模式,一般用protocol来实现。先写个protocol:


#import <UIKit/UIKit.h>

@protocol SwitchViewDelegate

-(void)getDetail;

@end


然后,需要让UIApplicationDelegate实现类实现该protocol:


#import <UIKit/UIKit.h>

#import "TopicController.h"

#import "SwitchViewDelegate.h"

@interface WindowDemoAppDelegate : NSObject
<UIApplicationDelegate,SwitchViewDelegate>
{

UIWindow
*window;

IBOutlet
TopicController *topicController;

}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end


在实现类中:


#import "WindowDemoAppDelegate.h"

#import "DetailController.h"

@implementation WindowDemoAppDelegate

@synthesize window;

#pragma mark –

#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

// Override
point for customization after application launch.

[self.window
addSubview:topicController.view];

topicController.delegate=self;


[self.window
makeKeyAndVisible];

return
YES;

}

- (void)applicationWillResignActive:(UIApplication *)application
{

}

- (void)applicationDidEnterBackground:(UIApplication
*)application {

}

- (void)applicationWillEnterForeground:(UIApplication
*)application {

}

- (void)applicationDidBecomeActive:(UIApplication *)application
{

}

- (void)applicationWillTerminate:(UIApplication *)application
{

}

#pragma mark –

#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication
*)application {

}

- (void)dealloc {

[window
release];

[super
dealloc];

}

-(void)getDetail{

DetailController *detailController=[[[DetailController alloc]
initWithNibName:@"DetailController" bundle:nil] autorelease];

self.window.rootViewController=detailController;

}


@end


另外,就是要为控制器里增加delegate属性,头文件:


#import <UIKit/UIKit.h>

#import "SwitchViewDelegate.h"

@interface TopicController : UIViewController {


id<SwitchViewDelegate>
delegate;


}

@property(nonatomic,retain)
id<SwitchViewDelegate>
delegate;


-(IBAction) getDetail:(id)sender;

@end


实现文件:


#import "TopicController.h"

#import "DetailController.h"

@implementation TopicController

@synthesize delegate;

-(IBAction) getDetail:(id)sender{

NSLog(@"get
detail …, window.views: %@",self.view.window.subviews);

[delegate
getDetail];
}


实现的效果和上面的是类似的,但是引入委托模式后,代码的架构就比较清楚了,利于以后的维护。

转自: http://marshal.easymorse.com/archives/4415
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐