2011年6月27日 星期一

iOS development: 實作兩個View


#import

@interface View_testViewController : UIViewController {
UIView *abc;//增加個名叫 abc View物件 
}

@property(nonatomic,retain) IBOutlet UIView *abc;

-(IBAction) buttonPressed:(id) sender;//切換用的按鈕

@end

在interfaceBuilder的library找到這個
有兩個View連到File's Owner去
原本的VIEW
新的abc
#import "View_testViewController.h"

@implementation View_testViewController

@synthesize abc;

-(IBAction) buttonPressed: (id) sender{
self.view= self.abc;//切換它
}


2011年6月26日 星期日

iOS development: Ch5-1 Autosize - Rotation

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    // return (interfaceOrientation == UIInterfaceOrientationPortrait); //只有 UIInterfaceOrientationPortrait這個狀況下才會回傳YES, 所以可以停用旋轉功能
// 如果你想開啟所有方向的話 就直接 return YES; 或是想要上下顛倒return (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
return YES;
/*旋轉到四個特定的方向的方法
 - UIInterfaceOrientationPortrait 
 - UIInterfaceOrientationPortraitUpsideDown
 - UIInterfaceOrientationLandscapeLeft
 - UIInterfaceOrientationLandscapeRight
*/
}
 利用Interface Builder來將每個按鈕改變視窗大小時的邊界固定就可以達到上面的樣子

將按鈕改為125*125大小
 轉個方向就會變這樣
我們不想要重疊就要覆寫方法來取代它

//宣告與建立新的接口
@interface Ch5_1_AutosizeViewController : UIViewController {
UIButton *button1;
UIButton *button2;
UIButton *button3;
UIButton *button4;
UIButton *button5;
UIButton *button6;
}

@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) IBOutlet UIButton *button2;
@property (nonatomic, retain) IBOutlet UIButton *button3;
@property (nonatomic, retain) IBOutlet UIButton *button4;
@property (nonatomic, retain) IBOutlet UIButton *button5;
@property (nonatomic, retain) IBOutlet UIButton *button6;
//宣告完後到interface builder 去連接接口
@end

==實作檔==========================

// 覆寫這個方法
#import "Ch5_1_AutosizeViewController.h"

@implementation Ch5_1_AutosizeViewController

@synthesize button1,button2,button3,button4,button5,button6;

-(void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation  
duration: (NSTimeInterval) duration{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){//固定預設狀況與上下顛倒的排列位置
button1.frame = CGRectMake(20, 20 , 125, 125);
button2.frame = CGRectMake(175, 20 , 125, 125);
button3.frame = CGRectMake(20, 168 , 125, 125);
button4.frame = CGRectMake(175, 168 , 125, 125);
button5.frame = CGRectMake(20, 315 , 125, 125);
button6.frame = CGRectMake(175, 315, 125, 125);
} else {//固定左右橫放的排列位置
button1.frame = CGRectMake(20, 20 , 125, 125);
button2.frame = CGRectMake(20, 155 , 125, 125);
button3.frame = CGRectMake(177, 20 , 125, 125);
button4.frame = CGRectMake(177, 155 , 125, 125);
button5.frame = CGRectMake(328, 20 , 125, 125);
button6.frame = CGRectMake(328, 155, 125, 125);
}
}


iOS development: Ch4 More User Interface


//  Ch4_1_More_Interface_ControlViewController.h
//  Ch4-1 More Interface Control
//
//  Created by jason on 2011/6/24.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import

#define kSwitchesSegmentIndex 0

@interface Ch4_1_More_Interface_ControlViewController : UIViewController { //使用動作表委派
UITextField *nameField; //用來給輸入name欄位
UITextField *numberField;//用來給輸入number欄位
UILabel *sliderLabel;//用來給輸出 sliderLabel
UISwitch *leftSwitch; //左按鈕
UISwitch *rightSwitch; //右按鈕
UIButton *doSomethingButton; // doSomething just do some thing
}

@property (nonatomic, retain) IBOutlet UITextField *nameField;
@property (nonatomic, retain) IBOutlet UITextField *numberField;
@property (nonatomic, retain) IBOutlet UILabel *sliderLabel;
@property (nonatomic, retain) IBOutlet UISwitch *leftSwitch,*rightSwitch;
@property (nonatomic, retain) IBOutlet UIButton *doSomethingButton;

-(IBAction) textFiledDoneEditing:(id) sender; //完成name輸入時要將鍵盤收回的方法
-(IBAction) backgroundTap:(id) sender;//當按到background時要將鍵盤收回的方法
-(IBAction) sliderChanged:(id) sender;//取得slider值與給值到slider label的方法
//下面這個方法會在點按分段控制項(swtich / Button )時被呼叫 因為doSomething按鈕會蓋住 switch 按鈕 用這個方法來顯示操作哪個按鈕
-(IBAction) toggleControls:(id) sender; 
-(IBAction) switchChanged: (id) sender; //switch按鈕的動畫
-(IBAction) buttonPressed;

@end

//  Ch4_1_More_Interface_ControlViewController.m
//  Ch4-1 More Interface Control
//
//  Created by jason on 2011/6/24.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Ch4_1_More_Interface_ControlViewController.h"

@implementation Ch4_1_More_Interface_ControlViewController

@synthesize nameField,numberField,sliderLabel,leftSwitch,rightSwitch,doSomethingButton;

-(IBAction) textFiledDoneEditing:(id) sender{
[sender resignFirstResponder]; //當輸入完成將控制權歸還以將鍵盤收回
}

-(IBAction) backgroundTap:(id) sender{//當使用者碰觸背景時將控制權歸還以將鍵盤收回
[nameField resignFirstResponder];
[numberField resignFirstResponder];
}

// slider bar 方法
-(IBAction) sliderChanged:(id) sender{ 
UISlider *slider = (UISlider *) sender;
int progressAsInt = (int)(slider.value +0.5f); //去掉小數點
NSString *newText= [[NSString alloc] initWithFormat:@"%d", progressAsInt]; // NSString
sliderLabel.text= newText;//指定給 sliderLabel
[newText release];
}

-(IBAction) toggleControls:(id) sender{ //這個方法會在點按分段控制項(swtich / Button )時被呼叫
if([sender selectedSegmentIndex] == kSwitchesSegmentIndex) //視狀況判斷決定要隱藏開關顯示按鈕或是隱藏按鈕顯示開關
{
leftSwitch.hidden = NO; //隱藏按鈕顯示開關
rightSwitch.hidden = NO;
doSomethingButton.hidden = YES;
}else{
leftSwitch.hidden = YES;//隱藏開關顯示按鈕
rightSwitch.hidden = YES;
doSomethingButton.hidden = NO;
}
}

-(IBAction) switchChanged: (id) sender{//點選任何開關都會被呼叫
UISwitch *whichSwitch= (UISwitch *) sender;// 取得是點按到哪個開關
BOOL setting = whichSwitch.isOn; // 取得開關是要開啟或是關閉
[leftSwitch setOn: setting animated: YES]; // [ setOn: (BOOL) animated: (BOOL)] => 第一個布林參數用來判斷要開啟或關閉,第二個布林參數用來讓它有動畫效果
[rightSwitch setOn: setting animated: YES];
}

-(IBAction) buttonPressed{
//配置一個代表動作表UIActionSheet的物件
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure?" // 標題
delegate:self  //self當委派參數傳送 
cancelButtonTitle:@"No Way!" //加入取消按鍵 
  destructiveButtonTitle:@"Yes, I'm sure!" //破壞性按鍵 
otherButtonTitles:nil]; //如果還要其他按鍵可以這樣 otherButtonTitle: @"Bar", @"Foo", nil];
[actionSheet showInView:self.view];// 建立完後就顯示出來 self.view = [self view] 
[actionSheet release];//釋放它
}

//找出是按下動作表的哪個按鈕
-(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex //因為剛剛以self做為回傳值,所以當委派開始就會啟動這個方法
{
// cancelButtonIndex 屬性是表示是不是按下取消按鈕
if(buttonIndex!=[actionSheet cancelButtonIndex])// 如果不是取消按鈕就是破壞性按鈕摟
{
NSString *msg=nil;
if(nameField.text.length > 0)//跟使用者講幾句話
msg=[[NSString alloc] initWithFormat:@"You can breathe easy, %@, everything went OK.", nameField.text];
else
msg = @"You canbreathe easy, everything went OK.";
//建立警示物件
UIAlertView *alert=[[UIAlertView alloc]
initWithTitle:@"Something DONE" //標題
message: msg //剛剛做的訊息
delegate: self 
cancelButtonTitle:@"Phew!" 
otherButtonTitles:nil];
[alert show];
[alert release];
[msg release];
}
}

// 覆寫Override viewDidLoad 將手指移過doSomething按鈕時,將白色按鈕圖案改為藍色按鈕 
-(void) viewDidLoad{
UIImage *buttonImageNormal = [UIImage imageNamed:@"whiteButton.png"]; //宣告一個物件 whiteButton.png指定給他 
UIImage *stretchableButtonImageNormal= [buttonImageNormal stretchableImageWithLeftCapWidth:12//將圖案伸展開來但是端點要維持原本的圓弧狀
  topCapHeight:0];//
[doSomethingButton setBackgroundImage:stretchableButtonImageNormal
forState:UIControlStateNormal]; //將它指定為按鈕的Normal狀態下的background
UIImage *buttonImagePressed = [UIImage imageNamed:@"blueButton.png"];
UIImage *stretchableButtonImagePressed= [buttonImagePressed stretchableImageWithLeftCapWidth:12
  topCapHeight:0];
[doSomethingButton setBackgroundImage:stretchableButtonImagePressed
forState:UIControlStateHighlighted]; //將它指定為按鈕Highlight狀態下的background
/*
iOS控制項 有四種狀態
-Normal: 預設狀態,若不在其他三個狀態的話就是這個狀態了
-Highlighted: 使用中以按鈕而言就是手指頭放在它上面
-Disable: 關閉停用 ,Interface Builder中可以設定
-selected: 只有部分控制項支援, 有點像Highlight但是他維持在這個狀態即使使用者沒有使用它了
*/
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload { //卸載所有參數的記憶體位置
self.nameField=nil;
self.numberField=nil;
self.sliderLabel=nil;
self.leftSwitch=nil;
self.rightSwitch=nil;
self.doSomethingButton=nil;
[super viewDidUnload];
}

- (void)dealloc {
[nameField release];
[numberField release];
[sliderLabel release];
[leftSwitch release];
[rightSwitch release];
[doSomethingButton release];
    [super dealloc];
}
@end

2011年6月21日 星期二

iOS development: Ch3-1 MVC - Practice Left Right Button

按下左右鍵可以顯示在上方藍色區域的簡單程式
我們將由這個練習了解到程式的運作與如何與MVC概念連結! 這個程式中有個顯示用的Lable, 有兩個Button! 程式於運行中將會取的按下按鈕的該按鍵的名稱加上 "button pressed." 字串並利用Label顯示出來!

建立Project 後我們會找到上圖的四個檔案! "xxx.h" 用來宣告物件, "xxx.m" 用來實作物件

Ch3_1_MVC___Practice_Left_Right_ButtonViewController.h
----------------------------------------------------------------------------------------

//  View controller 是個  "Controller" 用來control "view" 控制器 ,也就是 我們說的 MVC 中的 "C"
//  Ch3_1_MVC___Practice_Left_Right_ButtonViewController.h
//  Ch3-1 MVC - Practice Left Right Button
//
//  Created by jason on 2011/6/16.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import

// "Practice_Left_Right_ButtonViewController"這個物件是繼承 UIViewController 來的
// "UIViewController" 屬泛用控制器類別之一 , UIKit的一部分 
@interface Ch3_1_MVC___Practice_Left_Right_ButtonViewController : UIViewController 
{
UILabel *statusText; //控制器中唯一的變數,它將用來存放我們要顯示的內容(記得上次說的 MVC中的 View是不用來存放資料,通常會放在Controller)
}

//建立 View 接口 (IBOutlet) , 基本上 IBOutlet 什麼事也沒做,只是用來通知編譯器該變數會用來連接nib檔案中某物件的實例變數
//當我們開啟Project中的 nib or xib檔案時編譯器會去檢查標頭檔中是否有此關鍵字,並只讓這些變數連接到nib
@property (nonatomic, retain) IBOutlet UILabel *statusText; // @property 可以幫我們建立 setter and getter

// "Action"這個方法是屬於控制器類別, 使用 IBAction來宣告 
// 它將告訴 Interface Builder 此方法是個動作並可以用View控制項來觸發
// 還記得上次說的 MVC 中的 View會建一個Action 射向 Controller 中的 Target ,  buttonPressed就是它的 Target
-(IBAction) buttonPressed: (id) sender; //建立 IBAction 型態的 buttonPressed: 方法 , 利用 sender 取得傳給我們的物件資料 

@end

來實作Ch3_1_MVC___Practice_Left_Right_ButtonViewController.m
------------------------------------------------------------------------------------------

//
//  Ch3_1_MVC___Practice_Left_Right_ButtonViewController.m
//  Ch3-1 MVC - Practice Left Right Button
//
//  Created by jason on 2011/6/16.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Ch3_1_MVC___Practice_Left_Right_ButtonViewController.h"

@implementation Ch3_1_MVC___Practice_Left_Right_ButtonViewController
@synthesize statusText; // 這段程式讓compiler幫我們建立 getter setter兩種方法 所以我們有了statusText setStatusText這兩個隱藏方法 

// 我們會將這個方法連結到程式中的兩個按鈕,所以當這兩個按鈕不管誰被按到都會呼叫出這個方法
-(IBAction) buttonPressed:(id) sender {
NSString *title = [sender titleForState:UIControlStateNormal];// 利用 sender取得 button 的名稱 
NSString *newText=[[NSString alloc] initWithFormat:@"%@ button pressed.", title]; //將此名稱加上 button pressed. 字串
[statusText setText:newText]; //newText 給到 statusText 物件中 , statusText 是個UILabel的資料型態物件 , newText 則是 NSString
[newText release]; // newText 空間釋放
//以上四行可以用下面的程式取代
//statusText.text=[NSString stringWithFormat:@"%@ button pressed.",[sender titleForState:UIControlStateNormal]];
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.statusText=nil;
}


- (void)dealloc {
    [super dealloc];
[statusText release]; //這裡必要釋放記憶體
}

@end

Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate.h
------------------------------------------------------------------------------------
委派(delegate) - 委派指的是可負責代表另一個物件來執行某些工作的類別

應用程式的委派可以在某些預定好的時機代表UIApplication類別來做些事情
每個iPhone程式只有個 UIApplication實例,負責執行迴圈,處理層級,輸入導向..etc.
UIApplication UIKit的組成之一, 在程式執行的某個特定時機UIApplication會呼叫特定的委派方法
例如 : applicationWillTerminate:方法會在結束前啟動 ,可以把"結束"要用的程式碼放在這裡 

//這個檔案不用修改,由編譯器產生
//  Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate.h
//  Ch3-1 MVC - Practice Left Right Button
//
//  Created by jason on 2011/6/16.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import

@class Ch3_1_MVC___Practice_Left_Right_ButtonViewController;

@interface Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate : NSObject {
    UIWindow *window;
    Ch3_1_MVC___Practice_Left_Right_ButtonViewController *viewController;
}

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

@end

實作Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate.m
-------------------------------------------------------------------------------------
//
//  Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate.m
//  Ch3-1 MVC - Practice Left Right Button
//
//  Created by jason on 2011/6/16.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate.h"
#import "Ch3_1_MVC___Practice_Left_Right_ButtonViewController.h"

@implementation Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate

@synthesize window;
@synthesize viewController;


#pragma mark -
#pragma mark Application lifecycle

//應用程式開始完成設定,就開始下面的程式
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
       [self.window addSubview:viewController.view]; //在自己的window下開 subview
       [self.window makeKeyAndVisible]; //將window顯示出來

    return YES;
}

- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

@end
===================MainWindows.xib========================================


MainWindows.xib 是使應用程式的委派 , 主視窗 和檢視控制器實例得以建立
這個檔案由範本提供產生不用修改只是我們可以看看他是如何工作的
打開MainWindows.xib可以看到如下圖
圖中除了 File's Owner 與 First Responder 以外的圖示都會被實例化
所以會被實例化的有
Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate 的實例 
Ch3_1_MVC___Practice_Left_Right_ButtonViewController  的實例
UIWindow 的實例 


所以說一旦這個nib被載入後就會有一個 "委派" Ch3_1_MVC___Practice_Left_Right_ButtonAppDelegate,
一個檢視控制器Ch3_1_MVC___Practice_Left_Right_ButtonViewController
一個 UIWindow ( 在iOS 中 應用程式 只能有一個 window )


========Ch3_1_MVC___Practice_Left_Right_ButtonViewController.xib==========
點開xib開始作畫
點一下View開出View視窗
拖拉Library圖示做出此圖
將Label 與 File's Owner 連結並選取statusText


將Button 連接Touch Up Inside
事件與buttonPressed 連結藉以觸發這個方法! 以上完成..