zoukankan      html  css  js  c++  java
  • iOS 实现简单的界面切换

    以下是在iOS中最简单的界面切换示例。使用了多个Controller,并演示Controller之间在切换界面时的代码处理。

    实现的应用界面:

    imageimage

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

    image

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

    image

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

    创建TopicController:

    image

    这样将创建3个文件:

    image

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

    image

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

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

    先要拖拽一个View Controller进来:

    image

    然后,给View Controller改名:

    image

    下面,要把这个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文件中的视图颜色改为绿色:

    image

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

    image

    为该界面添加一个按钮:

    image

    为该按钮创建处理方法。在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连接:

    image

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

    image

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

    image

    然后,我需要点击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);
    }

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

    imageimage

    上面的代码做一下解释:

    • 首先创建了一个新的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

  • 相关阅读:
    愿你出走半生,归来多赚点钱
    喝下这碗毒鸡汤:作为一个『乖』学生,请一定要以学业为主!
    劝你理财,是我最大的温柔-lip师兄
    大半夜客户问我为什么这么拼,我给她算了笔账,她嚎啕大哭......
    女人为什么要经济独立
    定投6年以亏损收场,他到底做错了什么
    你的死工资,正在拖垮你&一辈子需要花多少钱
    字符串的长度
    泥塑课
    最大的数
  • 原文地址:https://www.cnblogs.com/stephen-init/p/4166715.html
Copyright © 2011-2022 走看看