IOS之UI基礎


2.1 增強版Hello World

2.2 MVC設計模式

2.3 Cocoa MVC

2.4 視圖控制器的方法

2.5 輸出口和動作

2.6 鍵盤輸入

2.7 使用AlertView

2.8 使用ActionSheet

2.8 等待有關控件

2.9 屏幕旋轉

 

2.1 增強版Hello World

wps_clip_image-10454

實現步驟

1.創建Hello World工程

在Xcode中創建Hello World工程,基於iPhone試圖基礎應用程序。

iPhone OS ->Application ->View-based Application

2.修改Hello_WorldViewController.h

需要UITextField控件接受文字和響應一個按鈕點擊事件,所以在h文件中我們要定義一個UITextField屬性和一個響應事件方法

#import <UIKit/UIKit.h>

@interface Hello_WorldViewController : UIViewController {
    UITextField *txtField;
}

@property (nonatomic, retain) IBOutlet UITextField *txtField;

-(IBAction)onClickButton:(id)sender;

@end

 

3.修改Hello_WorldViewController.m

   實現txtField屬性

   實現-(IBAction)onClickButton:(id)sender 方法

#import "Hello_WorldViewController.h"

@implementation Hello_WorldViewController

@synthesize txtField;

-(IBAction)onClickButton:(id)sender {
    txtField.text = @"Hello World.";
}

- (void)viewDidUnload {
    self.txtField = nil;
}

- (void)dealloc {
    [txtField dealloc];
    [super dealloc];
}

@end

 

4.使用IB設計頁面,擺放控件

Resources/Hello_WorldViewController.xib文件,打開Library將控件拖入設計窗口

wps_clip_image-7058

5.連接輸出口

為了將控件屬性通過屏幕“輸入”或“輸出”,我們需要定義“輸出口”,在控制器中我們已經定義了與這個數據對 應的屬性:

@property (nonatomic, retain)  IBOutlet

UITextField *txtField;

UITextField用於展示輸出和輸入數據。在iPhone(包括Mac)開發時候控件屬性要通過定義輸出口才能在屏幕中使用 的。

wps_clip_image-23933

6.處理事件

為了響應控件的事件,我們需要在控制器中定義一個事件處理方法:

-(IBAction)onClickButton:(id)sender;

在iPhone(包括Mac)開發控件事件處理要自己編寫對應方法,並在IB中將控件的事件與該方法連接起來。

wps_clip_image-13768

2.2 MVC設計模式

MVC是一種設計模式,所謂設計模式就是解決某一特定問題的方案,MVC是解決具有UI的應用系統的成熟解決方案,

在Cocoa應用系統中嚴格按照該模式實現。M-Model(模型)是應用系統中與視圖對於部分的數據。V -View(視圖)是應用系統中用戶看到並與之交互的界面。C-Controller(控制器)是應用系統中起到控制器作用,接受用戶事件,顯示數據等等,與視圖進行交互等。

2.3 Cocoa MVC

采用MVC 設計模式意味着,Interface Builder 不需要編寫或生成任何代碼,您只需專注於應用程序的視圖。Mac 的Cocoa 綁定消除了大部分的黏合代碼,它就像連接在Xcode 編寫的控制器和Interface Builder 設計的視圖之間的一條線,用圖形化的表示方法簡化了二者之間的關系。Interface Builder 和Cocoa 可以快速開發地您的應用程序。

wps_clip_image-32174

File's owner:

wps_clip_image-29401

2.4 視圖控制器的方法

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

如果視圖使用NIB文件創建,在加載視圖之前調用這個方法,做一些初始化工作。

- (void)loadView

視圖加載的時候調用的方法一般不使用NIB文件創建視圖的時候使用,而是使用代碼創建視圖對象。

- (void)viewDidLoad 

視圖加載之后調用的方法,我們常常在這個方法中做視圖初始化出來。

- (void)didReceiveMemoryWarning

當系統內存警告的時候調用的方法,我們一般在該方法釋放消耗資源的對象。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

用於處理屏幕旋轉的方法。

- (void)viewDidUnload 

視圖對象卸載的使用調用的方法,一般在把內存視圖中的屬性設置為nil值。

- (void)viewDidUnload {
    self.txtField = nil;
}

 

- (void)dealloc

視圖對象內存釋放的時候調用的方法,在該方法中先要釋放掉成員變量。

- (void)dealloc {
    [txtField dealloc];
    [super dealloc];
}

 

2.5 輸出口和動作

輸出口(Outlet),為了實現控制器在視圖上輸入輸出結果,需要定義輸出口。

定義輸出口,是在ViewController定義一個控件屬性,如下:

//h文件
@interface Hello_WorldViewController : UIViewController {
    UITextField *txtField;
}

@property (nonatomic, retain) IBOutlet UITextField *txtField;

//m文件
@synthesize txtField;

動作(Action),為了實現視圖控制器響應視圖事件,需要定義動作。

定義動作,是在ViewController定義一個方法,如下:

//h文件
-(IBAction)onClickButton:(id)sender;

//m文件
-(IBAction)onClickButton:(id)sender {
    txtField.text = @"Hello World.";
}

動作(Action)是在控件器中的方法,但它的返回類型必須是IBAction聲明的,該關鍵字告訴IB,此方法是個Action,可以被某個事件觸發。

2.6 鍵盤輸入

在iPhone應用程序中,鍵盤輸入處理比較麻煩。在輸入完成后我們需要自己關閉鍵盤。

在iPhone中我們還可以指定鍵盤輸入類型,可以是Email、電話和數字等類型。

輸入完成關閉鍵盤:

Phone中文本框輸入后,鍵盤是不會關閉的,必須編寫代碼。

1 為關閉鍵盤添加事件處理方法:

//h file
-(IBAction)textFieldDoneEditing:(id)sender;

//m file
-(IBAction)textFieldDoneEditing:(id)sender {
    [sender resignFirstResponder];    
}

2 鏈接事件

文本框對象的Did End On Exit事件鏈接到File’s  Owner。

wps_clip_image-11610

wps_clip_image-26608

3 小結

點擊鍵盤中的“換行”或“return”鍵關閉鍵盤。 第一響應者是當前與用戶交互的控件,在這個例子中,點擊TextField控件,它就變成第一響應者鍵盤就會自動出現。

[sender resignFirstResponder];

是使TextField控件放棄第一響應者狀態。

4 通過觸摸背景關閉鍵盤

點擊關閉鍵盤中的“return”關閉鍵盤比較麻煩,我們可以通過觸摸背景關閉鍵盤。

//h
-(IBAction)backgroundTap:(id)sender;

//m
-(IBAction)backgroundTap:(id)sender {
    [txtField resignFirstResponder];    
}

5 連接動作和事件

為了使背景控件能夠響應事件,我們需要背景View的父類(UIView)修改成為UIControl,UIControl是能夠觸發actionɼ所有控件都是UIControl的子類。而UIControl是UIView子類,也具有View基本特征。

從Touch Down事件拖到File’s Owner圖標,然后選擇backgroundTap:動作。這樣觸摸視圖中沒有活動的控件的任何位置就可以觸發backgroundTap:動作,關閉鍵盤。

wps_clip_image-9817

6 鍵盤輸入類型

在iPhone中我們還可以指定鍵盤輸入類型,可以是Email、電話和數字等類型。

wps_clip_image-21337

Email鍵盤                         數字鍵盤                        電話鍵盤

wps_clip_image-26960wps_clip_image-23738wps_clip_image-32252

7 Return Key設定

在鍵盤輸入屬性框中我們可以定義Return Key,可以有Google等等。但是這些並沒有實際的含義,只是代表它可以觸發輸入完成事件(Did End On Exit)。

2.7 使用AlertView

修改Hello World項目代碼,添加AlertView:

修改Hello-.m代碼

-(IBAction)onClickButton:(id)sender {
    
    //txtField.text = @"Hello World.";
    NSString *str = [[NSString alloc] initWithFormat:@"Hello. %@", txtField.text];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" 
                                        message:str delegate:self 
                                        cancelButtonTitle:@"Done" 
                                        otherButtonTitles:nil];
    [alert show];
    [alert release];
    [str release];
    
}

 

2.8 使用ActionSheet

ActionSheet和AlertView比較相似都是給用戶一個提示信息。它是從底部彈出。它通常用於確認潛在的危險或不能撤消的操作,如刪除一個數據。 為了使用ActionSheet我們需要在h文件中實現UIActionSheetDelegate協議。其中,我們常常需

要實現: actionSheet:didDismissWithButtonIndex:

該方法是ActionSheet消失的時候調用。

wps_clip_image-21640

修改Hello-.h文件

在Hello_WorldViewController.h文件中添加協議UIActionSheetDelegate:

//h
#import <UIKit/UIKit.h>

@interface Hello_WorldViewController : UIViewController 
        <UIActionSheetDelegate> {
    UITextField *txtField;
}

@property (nonatomic, retain) IBOutlet UITextField *txtField;

-(IBAction)onClickButton:(id)sender;

@end

 

//m
#import "Hello_WorldViewController.h"

@implementation Hello_WorldViewController

@synthesize txtField;

-(IBAction)onClickButton:(id)sender {
    
    //txtField.text = @"Hello World.";
    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                                  initWithTitle:@"您確認清除文本框中的數據嗎?" 
                                  delegate:self 
                                  cancelButtonTitle:@"取消" 
                                  destructiveButtonTitle:@"確定" 
                                  otherButtonTitles:nil];
    
//    NSArray *array = [[NSArray alloc] initWithObjects:
//                      [NSString stringWithString:@"1st Button"],
//                      [NSString stringWithString:@"2nd Button"],
//                      [NSString stringWithString:@"3rd Button"],
//                      [NSString stringWithString:@"4th Button"],
//                      nil];
//    
//    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Title Here"
//                                                             delegate:self
//                                                    cancelButtonTitle:nil
//                                               destructiveButtonTitle:nil
//                                                    otherButtonTitles:nil];
//    
//    for (int i = 0; i < 3; i++) {
//        
//        [actionSheet addButtonWithTitle:[array objectAtIndex:i]];
//        
//    }
//    
//    [actionSheet addButtonWithTitle:@"Cancel"];
//    actionSheet.cancelButtonIndex = 4;
    
    [actionSheet showInView:self.view];
    [actionSheet release];    
}

-(void)actionSheet:(UIActionSheet *)actionSheet 
            didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (buttonIndex == [actionSheet destructiveButtonIndex]) {
        txtField.text = @"";    
    }
}

- (void)viewDidUnload {
    self.txtField = nil;
}


- (void)dealloc {
    [txtField dealloc];
    [super dealloc];
}

@end

 

2.8 等待有關控件

對於一些費時的處理,需要使用一些等待控件消除用戶心里等待的時間。

等待有關的控件有:

" UIActivityIndicatorView

" UIProgressView

UIActivityIndicatorView:

wps_clip_image-26447

UIActivity-.h

@interface UIActivityIndicatorViewController : UIViewController {
    UIActivityIndicatorView * myActivityView;
}

@property (nonatomic, retain) IBOutlet UIActivityIndicatorView * myActivityView;

-(IBAction)onClickButton: (id)sender;

@end

 

UIActivity-.m

#import "UIActivityIndicatorViewController.h"

@implementation UIActivityIndicatorViewController

@synthesize myActivityView;

-(IBAction)onClickButton: (id)sender {
    if ([myActivityView isAnimating]) {
        [myActivityView stopAnimating];            
    } else {
        [myActivityView startAnimating];
    }
}

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

@end

 

UIProgressView

wps_clip_image-24783

Progress-.h

@interface ProgressViewViewController : UIViewController {
    IBOutlet UIProgressView *Progress; 
    NSTimer *timer;
}

@property (nonatomic, retain) IBOutlet UIProgressView *Progress; 
@property (nonatomic, assign) NSTimer *timer;
    
-(IBAction)start;

@end

 

Progress-.m

@synthesize  Progress;
@synthesize timer;

- (void)viewDidLoad {
    [super viewDidLoad];
}

-(IBAction)start{
    Progress.progress = 0.0;
    timer = [NSTimer 
             scheduledTimerWithTimeInterval:1.0 
             target:self 
             selector:@selector(update) 
             userInfo:nil repeats:YES];
}

 

NSTimer是可以隱式地啟動一個線程,scheduledTimerWithTimeInterval指定線程要休眠多少時間調用一次,selector所指定的方法update

Progress-.m

-(void)update{
    Progress.progress = Progress.progress + 0.1;
    if (Progress.progress == 1.0) {
        [timer invalidate]; 
        UIAlertView *alert = [[UIAlertView alloc] 
                              initWithTitle:@"任務通知" 
                              message:@"硬盤格式化完成!" 
                              delegate:self 
                              cancelButtonTitle:@"OK" 
                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}

- (void)viewDidUnload {
    self.Progress = nil;
}


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

 

UIProgressView控件的progress屬性是0.0~1.0煩范圍。0.0時候在開始的位置,1.0時候是進度到了100%。

2.9 屏幕旋轉

iPhone中有重力感應我們可以通過旋轉手機使屏幕旋轉。但是屏幕旋轉后頁面的布局需要注意。

wps_clip_image-30651

屏幕旋轉的類型

UIInterfaceOrientationPortrait,垂直向上

UIInterfaceOrientationPortraitUpsideDown,垂直倒放。

UIInterfaceOrientationLandscapeLeft,水平向左。

UIInterfaceOrientationLandscapeRight,水平向右。

注意:以手機屏幕為參照物的向左、向右。

開啟旋轉 :可以通過shouldAutorotateToInterfaceOrientation:方法開啟或禁止旋轉。

允許任何方向的旋轉:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

 

垂直向上和水平向右:

- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration {
    if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        
    } else {
        
    }
}

 

觸發旋轉事件 :

我們可以在屏幕旋轉的時候觸發很多事件,其中willAnimateRotationToInterfaceOrientation是我們常用的事件,這個事件是在即將開始屏幕旋轉動畫的時候觸發。

- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration {
    if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        txtField.text = @"垂直顯示。";
    } else {
        txtField.text = @"水平顯示。";
    }
}

 

自動調整屏幕控件

由於屏幕旋轉后,控件的位置會發生變化,我們要讓這些控件能夠擺放相對比較合理。我們可以通過“Control Size”調整。 其中紅色實線代表絕對位置, 紅色虛線代表相對位置。

wps_clip_image-31232

橫屏豎屏切換不同視圖

wps_clip_image-1221

新建工程Swap

SwapViewController.h文件

#import <UIKit/UIKit.h>
#define degreesToRadians(x) (M_PI * (x) / 180.0)

@interface SwapViewController : UIViewController {
    UIView *landscape; 
    UIView *portrait; 
    
    UIButton *landscapeFooButton;//Foo
    UIButton *portraitFooButton; 
    
    UIButton *landscapeBarButton;//Bar 
    UIButton *portraitBarButton;
} 

@property (nonatomic, retain) IBOutlet UIView *landscape; 
@property (nonatomic, retain) IBOutlet UIView *portrait; 
@property (nonatomic, retain) IBOutlet UIButton *landscapeFooButton; 
@property (nonatomic, retain) IBOutlet UIButton *portraitFooButton; 
@property (nonatomic, retain) IBOutlet UIButton *landscapeBarButton; 
@property (nonatomic, retain) IBOutlet UIButton *portraitBarButton; 

-(IBAction) buttonPressed:(id)sender;


@end

 

#define degreesToRadians(X) (M_PI * (x) / 180.0)這是一個宏,用於在度數和弧度之間的轉換。

landscape水平視圖,portrait垂直視圖;

landscapeFooButton水平視圖中Foo按鈕;

portraitFooButton垂直視圖中Foo按鈕;

landscapeBarButton水平視圖中Bar按鈕;

portraitBarButton垂直視圖中Bar按鈕。

視圖設計

wps_clip_image-2323

輸出口和事件 

wps_clip_image-22664

編寫m實現文件

#import "SwapViewController.h"

@implementation SwapViewController

@synthesize landscape; 
@synthesize portrait; 
@synthesize landscapeFooButton; 
@synthesize portraitFooButton; 
@synthesize landscapeBarButton; 
@synthesize portraitBarButton; 

-(IBAction) buttonPressed:(id)sender {
    if (sender == portraitFooButton) {
        NSLog(@"portraitFooButton press.");
    } else if (sender == landscapeFooButton) {
        NSLog(@"landscapeFooButton press.");
    } else if (sender == landscapeBarButton) {
        NSLog(@"landscapeBarButton press.");
    } else {
        NSLog(@"portraitBarButton press.");
    }
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    //return (interfaceOrientation == UIInterfaceOrientationPortrait);
    return YES;
}

-(void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation duration: (NSTimeInterval)duration{
    
    if (interfaceOrientation == UIInterfaceOrientationPortrait) {
        self.view = self.portrait; 
        self.view.transform = CGAffineTransformIdentity; 
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0));
        self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
    } else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        self.view = self.landscape; 
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90));
        self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
    } else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        self.view = self.portrait; 
        self.view.transform = CGAffineTransformIdentity; 
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(180)); 
        self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
    } else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        self.view = self.landscape; 
        self.view.transform = CGAffineTransformIdentity; 
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); 
        self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
    }
    
}

- (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.
    self.landscape = nil;
    self.portrait = nil;
    self.landscapeFooButton = nil;
    self.portraitFooButton = nil;
    self.landscapeBarButton = nil;
    self.portraitBarButton = nil;
}


- (void)dealloc {
    [landscape release]; 
    [portrait release]; 
    [landscapeFooButton release]; 
    [portraitFooButton release]; 
    [landscapeBarButton release];  
    [portraitBarButton release]; 
    [super dealloc];
}

@end

 

willAnimateRotationToInterfaceOrientationduration:這個方法來自我們重寫的一個父類,這個方法在旋轉開始之后與旋轉實際發生之前被調用。

CGAffineTransformIdentity,重置變換屬性。

CGAffineTransformMakeRotation來創建一個旋轉變換。

注:

1 本教程是基於關東升老師的教程

2 基於黑蘋果10.6.8和xcode4.2

3 本人初學,有什么不對的望指教

4 教程會隨着本人學習,持續更新

5 教程是本人從word筆記中拷貝出來了,所以格式請見諒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM