以下是在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

iOS 实现简单的界面切换的更多相关文章

  1. 编写最简单的 iPhone 界面切换应用

    编写最简单的 iPhone 界面切换应用   以下是在iOS中最简单的界面切换示例.使用了多个Controller,并演示Controller之间在切换界面时的代码处理. 实现的应用界面: 首先,创建 ...

  2. [android] 界面切换的核心方法

    根据效果图拆分界面 主体部分 View ==> ViewGroup ==> RelativeLayout,主体部分使用RelativeLayout作为占位 View和ViewGroup的区 ...

  3. Unity iOS混合开发界面切换思路

    Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...

  4. iOS 简单引导界面

    代码地址如下:http://www.demodashi.com/demo/11607.html 前言 现在很多APP在用户第一次用的时候,由于用户可能并不知道其中一些功能点的时候,这个时候就需要我们来 ...

  5. iOS开发简单介绍

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的iOS程序.但是这里我想强调一下,前面的 ...

  6. Linux启动界面切换:图形界面-字符界面(转)

    Linux字符界面切换到图形界面 由字符界面切换到图形界面可用两种简单方法实现: 1.在字符界面输入startx或init 5 . 2.通过编辑/etc/inittab文件实现默认进入图形界面. 把其 ...

  7. Html5 Egret游戏开发 成语大挑战(五)界面切换和数据处理

    经过前面的制作,使用Egret的Wing很快完成了开始界面和选关卡界面,下面通常来说就是游戏界面,但此时界面切换和关卡数据还没有准备好,这次讲解界面的切换和关卡数据的解析.前面多次修改了Main.ts ...

  8. 参考_Android中,如何新建一个界面,并且实现从当前界面切换到到刚才新建的(另外一个)界面

    参考地址: http://www.crifan.com/android_how_to_create_new_ui_and_switch_to_another_new_ui/ 想要实现,在Android ...

  9. WPF如何实现类似iPhone界面切换的效果(转载)

    WPF如何实现类似iPhone界面切换的效果 (version .1) 转自:http://blog.csdn.net/fallincloud/article/details/6968764 在论坛上 ...

随机推荐

  1. [atAGC034F]RNG and XOR

    令$N=2^{n}$先将$\forall 0\le i<N,a_{i}$除以$\sum_{i=0}^{N-1}a_{i}$,即变为概率 令$f_{i}$表示$i$的答案(第一次变成$i$的期望步 ...

  2. [bzoj3670]动物园

    首先计算出s数组,s表示可以重复的前缀等于后缀的个数,显然有s[i]=s[next[i]]+1,因为有且仅有next的next满足这个条件. 然后直接暴力枚举所有next,直到它小于i的一半,这个时间 ...

  3. [bzoj5418]屠龙勇士

    很显然,每一步所选的剑和怪物都是确定的,可以先求出来(不用写平衡树,直接用multiset即可,注意删除要删指针,以下假设第i次攻击用ki攻击的剑,攻击第i只怪)  首先判断无解,即如果存在ai使得g ...

  4. [uva11429]Randomness

    记p(i,j)表示第i次随机时,用多少个数对应到第j个事件,特别的,p(i,0)表示转移到下一次随机数的概率,那么即要求$aj/bj=\sum_{i=1}^{inf}p(i,j)/R^{i}$,容易发 ...

  5. negix安装与配置2-反向代理一台

    negix反向代理: 1.实现效果:打开浏览器,输入www.123.com 跳转到linux系统主页面中 2.准备工作tomcat java环境 https://www.cnblogs.com/q13 ...

  6. 日程功能模块【从建模到代码实现】UML + JavaFX

    结合 uml 所学和 Javafx 从建模到实现一个子功能模块 -- 日程管理.新手上路,类图到代码实现的过程还是很曲折但所幸收获颇丰,记录一下学习心得. 日程功能模块 最后成果 JAVAFX里面没有 ...

  7. ElasticJob分布式任务调度应用v2.5.2

    为何要使用分布式任务调度 **本人博客网站 **IT小神 www.itxiaoshen.com 演示项目源码地址** https://gitee.com/yongzhebuju/spring-task ...

  8. 树形DP详解+题目

    关于树形dp 我觉得他和线性dp差不多 总结 最近写了好多树形dp+树形结构的题目,这些题目变化多样能与多种算法结合,但还是有好多规律可以找的. 先说总的规律吧! 一般来说树形dp在设状态转移方程时都 ...

  9. 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  10. 洛谷 P4749 - [CERC2017]Kitchen Knobs(差分转换+dp,思维题)

    题面传送门 一道挺有意思的思维题. 首先有一个 obvious 的结论,就是对于每个炉子,要么转到哪里都符合条件,要么存在唯一的最大值.对于转到哪儿都符合条件的炉子我们 duck 不必考虑它,故我们只 ...