標籤:style http ar io color os 使用 sp for
以下是在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;
IBOutletTopicController *topicController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
在實現檔案中:
#import "WindowDemoAppDelegate.h"
@implementation WindowDemoAppDelegate
@synthesize window;
#pragma mark –
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
// Overridepoint for customization after application launch.
[self.windowaddSubview:topicController.view];
[self.windowmakeKeyAndVisible];
returnYES;
}
然後,為了看的清楚,把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(@"getdetail …");
}
在IB中,將按鈕和控制器的Action串連:
再次運行應用,可看到日誌中的列印內容:
按照上面建立Controller的方法,再建立一個DetailController。先把DetailController.xib的視圖設定顏色,為了以後調試觀察識別。
然後,我需要點擊TopicController視圖中按鈕切換到DetailController視圖。這需要在下面代碼中想辦法:
#import "TopicController.h"
@implementation TopicController
-(IBAction) getDetail:(id)sender{
NSLog(@"getdetail …");
}
基本思路是找到window執行個體,可通過window的rootViewController屬性設定新的控制器執行個體(比如DetailController),取代TopicController。代碼可這樣寫:
#import "TopicController.h"
#import "DetailController.h"
@implementation TopicController
-(IBAction) getDetail:(id)sender{
NSLog(@"getdetail …, 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;
IBOutletTopicController *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 *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
// Overridepoint for customization after application launch.
[self.windowaddSubview:topicController.view];
topicController.delegate=self;
[self.windowmakeKeyAndVisible];
returnYES;
}
- (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 {
[windowrelease];
[superdealloc];
}
-(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(@"getdetail …, window.views: %@",self.view.window.subviews);
[delegategetDetail];
}
實現的效果和上面的是類似的,但是引入委託模式後,代碼的架構就比較清楚了,利於以後的維護。
轉自: http://marshal.easymorse.com/archives/4415
iOS 實現簡單的介面切換