iOS 实现简单的界面切换
以下是在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];
}
实现的效果和上面的是类似的,但是引入委托模式后,代码的架构就比较清楚了,利于以后的维护。
iOS 实现简单的界面切换的更多相关文章
- 编写最简单的 iPhone 界面切换应用
编写最简单的 iPhone 界面切换应用 以下是在iOS中最简单的界面切换示例.使用了多个Controller,并演示Controller之间在切换界面时的代码处理. 实现的应用界面: 首先,创建 ...
- [android] 界面切换的核心方法
根据效果图拆分界面 主体部分 View ==> ViewGroup ==> RelativeLayout,主体部分使用RelativeLayout作为占位 View和ViewGroup的区 ...
- Unity iOS混合开发界面切换思路
Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...
- iOS 简单引导界面
代码地址如下:http://www.demodashi.com/demo/11607.html 前言 现在很多APP在用户第一次用的时候,由于用户可能并不知道其中一些功能点的时候,这个时候就需要我们来 ...
- iOS开发简单介绍
概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的iOS程序.但是这里我想强调一下,前面的 ...
- Linux启动界面切换:图形界面-字符界面(转)
Linux字符界面切换到图形界面 由字符界面切换到图形界面可用两种简单方法实现: 1.在字符界面输入startx或init 5 . 2.通过编辑/etc/inittab文件实现默认进入图形界面. 把其 ...
- Html5 Egret游戏开发 成语大挑战(五)界面切换和数据处理
经过前面的制作,使用Egret的Wing很快完成了开始界面和选关卡界面,下面通常来说就是游戏界面,但此时界面切换和关卡数据还没有准备好,这次讲解界面的切换和关卡数据的解析.前面多次修改了Main.ts ...
- 参考_Android中,如何新建一个界面,并且实现从当前界面切换到到刚才新建的(另外一个)界面
参考地址: http://www.crifan.com/android_how_to_create_new_ui_and_switch_to_another_new_ui/ 想要实现,在Android ...
- WPF如何实现类似iPhone界面切换的效果(转载)
WPF如何实现类似iPhone界面切换的效果 (version .1) 转自:http://blog.csdn.net/fallincloud/article/details/6968764 在论坛上 ...
随机推荐
- Roslyn 编译器Api妙用:动态生成类并实现接口
在上一篇文章中有讲到使用反射手写IL代码动态生成类并实现接口. 反射的妙用:C#通过反射动态生成类型继承接口并实现 有位网友推荐使用 Roslyn 去脚本化动态生成,今天这篇文章就主要讲怎么使用 Ro ...
- vue-ref指令
$refs是数组
- 『学了就忘』Linux文件系统管理 — 60、Linux中配置自动挂载
目录 1.自动挂载 2.如何查询系统下每个分区的UUID 3.配置自动挂载 4./etc/fstab文件修复 上一篇文章我们说明了手动分区讲解,对一块新硬盘进行了手动分区和挂载. 但是我们发现重启系统 ...
- python3使用concurrent执行多进程任务
技术背景 随着计算机技术的发展,诸如GPU和超算平台等越来越发达,这些技术的本质其实并没有带来算法上的革新,之所以能够提升计算的速度和规模,很大程度上是因为分布式和并行计算的优势.这里我们介绍一个简单 ...
- Codeforces 1553I - Stairs(分治 NTT+容斥)
Codeforces 题面传送门 & 洛谷题面传送门 u1s1 感觉这道题放到 D1+D2 里作为 5250 分的 I 有点偏简单了吧 首先一件非常显然的事情是,如果我们已知了排列对应的阶梯序 ...
- Codeforces 571E - Geometric Progressions(数论+阿巴细节题)
Codeforces 题目传送门 & 洛谷题目传送门 u1s1 感觉此题思维难度不太大,不过大概是细节多得到了精神污染的地步所以才放到 D1E 的罢((( 首先我们对所有 \(a_i,b_i\ ...
- 【豆科基因组】大豆适应性位点GWAS分析 [转载]
目录 材料与方法 结果分析 本文利用99085个高质量SNP 通过STRUCTURE,PCA和neighbour-joining tree的群体结构分析将地方品种分为三个亚群,这些亚群表现出地理上的遗 ...
- Nginx+uwsgi+django+vue部署项目
购买服务器 # 购买阿里云服务器 # 短期或是测试使用,创建 按量收费 服务器,可以随时删除,删除后不再计费,但要保证账户余额100元以上 连接服务器 1)账号 >: ssh root@39.9 ...
- pyyaml模块
pyyaml模块是一种文件数据处理格式的方法,常用与生成.解析或修改.yaml配置文件 1.常见.yaml文件格式内容如下 languages: - Ruby - Perl - Python webs ...
- nrf 51802 和 nrf51822 的区别于联系
51802QFAA与51822QFAA在FLASH 跟RAM的容量没有差别:区别在于:a,接收灵敏度 51802是-91dBm;51822是-93dBm,这个差异导致接收距离有差异:b,Tx Powe ...