IOS之導航控制器與表視圖


7.1 導航控制器

7.2 創建第一級控制器

7.3 第一個二級控制器

7.4 第一個三級控制器

7.5 第二個二級表控制器

7.6 第三個二級表控制器

7.7 第四個二級表控制器

7.8 第五個二級表視圖控制器

7.8 第六個二級表視圖控制器

 

 

7.1 導航控制器

關於導航控制器和表視圖

導航控制器和表視圖密不可分。嚴格的說,要完成導航控制器的功能並不需要表視圖。然而,在實際的應用程序中使用導航控制器時,幾乎總是要實現至少一個表,並且通常多個表,因為導航控制器的強大之處在於它能夠處理復雜的分層數據,在iPhone的小屏幕上,連續的使用表示分層數據最理想的方式。

wps_clip_image-5271

7.2 創建第一級控制器

一級控制器RootViewController還是一個UITableViewController,它並不是我們說的導航控制器,我們在委托Delegate中定義了導航控制器UINavigationController,事實上UINavigationController才真正意義的根控制器。

RootViewController.h

#import <UIKit/UIKit.h>

@interface RootViewController : UITableViewController {
    NSArray *controllers;
}

@property (nonatomic, retain) NSArray *controllers;

@end

RootViewController.m

@implementation RootViewController

@synthesize controllers;

- (void)viewDidLoad {
    self.title = @"First Level";
    NSMutableArray *array = [[NSMutableArray alloc] init];
    //增加控制器
    //
    self.controllers = array;
    [array release];
    [super viewDidLoad];
}

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

- (void)viewDidUnload {
}

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

實現TableView數據源方法

#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [controllers count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSInteger row = [indexPath row];
    SecondLevelViewController *controller = [controllers objectAtIndex:row];
    cell.textLabel.text =  controller.title;
    cell.imageView.image = controller.rowImage;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    return cell;
}

cell.accessoryType屬性設定表視圖單元格擴展圖標類型。單元格擴展圖標類型:

UITableViewCellAccessoryNone,沒有擴展圖標;

UITableViewCellAccessoryDisclosureIndicator,擴展指示器,觸摸該圖標將切換到下一級表視圖,圖標為wps_clip_image-19307

UITableViewCellAccessoryDetailDisclosureButton,細節展示按鈕,觸摸該行將顯示當前行的更多詳細信息視圖,圖標為wps_clip_image-30087

UITableViewCellAccessoryCheckmark,選中標志,當選中某一行時候標志該行,圖標為wps_clip_image-18845

實現TableView委托方法

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSInteger row = [indexPath row];
    SecondLevelViewController *nextController = [self.controllers objectAtIndex:row];
    [self.navigationController pushViewController:nextController animated:YES];
}

二級表視圖控制器

由於二級控制器也是表視圖控制器,而且我們需要在為每個頁面指定一個圖片,所以我們定義了一個父類SecondLevelViewController

SecondLevelViewController

@interface SecondLevelViewController : UITableViewController {
    UIImage *rowImage;
}
@property (nonatomic, retain) UIImage *rowImage;

@end
#import "SecondLevelViewController.h"

@implementation SecondLevelViewController

@synthesize rowImage;

@end

7.3 第一個二級控制器

wps_clip_image-9186

DisclosureButtonController.h

#import <Foundation/Foundation.h>
#import "SecondLevelViewController.h"
#import "DisclosureDetailController.h"

@interface DisclosureButtonController : SecondLevelViewController {
    NSArray *listData;
    DisclosureDetailController *childController;
}
@property (nonatomic,retain) NSArray *listData;
@property (nonatomic, retain) DisclosureDetailController *childController;

@end

DisclosureButtonController.m

#import "DisclosureButtonController.h"
#import "SecondLevelViewController.h"

@implementation DisclosureButtonController

@synthesize listData;
@synthesize childController;

- (void)viewDidLoad {
    NSArray *array = [[NSArray alloc] initWithObjects:@"Toy Story",
                      @"A Bug's Life", @"Toy Story 2", @"Monsters, Inc.", 
                      @"Finding Nemo", @"The Incredibles", @"Cars", 
                      @"Ratatouille", @"WALL-E", @"Up", @"Toy Story 3",
                      @"Cars 2", @"The Bear and the Bow", @"Newt", nil];
    self.listData = array;
    [array release];
    
    [super viewDidLoad];
}

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


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

實現TableView數據源方法

#pragma mark -
#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [listData count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSInteger row = [indexPath row];
    NSString *title = [listData objectAtIndex:row];
    cell.textLabel.text =  title;
    //cell.imageView.image = controller.rowImage;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    
    return cell;
}

實現TableView委托方法

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (childController == nil) {
        childController = [[DisclosureDetailController alloc] 
                           initWithNibName:@"DisclosureDetailController" 
                           bundle:nil];
    }
    //childController.title = @"DisclosureDetail Button Pressed";
    NSInteger row = [indexPath row];
    NSString *selectedMessage = [listData objectAtIndex:row];
    
    NSString *message = [[NSString alloc] initWithFormat:@"你選擇了 %@ 按鈕。", selectedMessage];
    childController.message = message;
    childController.title = selectedMessage;
    
    [message release];
    
    [self.navigationController pushViewController:childController animated:YES];
}

上面的委托方法,是用戶選中單元格后觸發的方法。

[self.navigationController pushViewController:childController animated:YES];

是將詳細視圖控制器放置到導航控制器棧中,並以動畫效果顯示詳細視圖。

RootViewController中 viewDidLoad方法

    //增加細節擴展按鈕控制器
    DisclosureButtonController *disclosureButtonController = [[DisclosureButtonController alloc] 
                                                initWithStyle:UITableViewStylePlain];
    
    disclosureButtonController.title = @"Disclosure Buttons";
    disclosureButtonController.rowImage = [UIImage imageNamed:@"disclosureButtonControllerIcon.png"];
    [array addObject:disclosureButtonController];
    [disclosureButtonController release];

7.4 第一個三級控制器

wps_clip_image-11346

DisclosureDetailController.h

@interface DisclosureDetailController : UIViewController {
    UILabel *label;
    NSString *message;
}
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) NSString *message;

@end

message從上一個屏幕傳遞過來的消息 label顯示消息的控件。

m文件中的初始化方法

@implementation DisclosureDetailController

@synthesize message;
@synthesize label;


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewWillAppear:(BOOL)animated {
    label.text = message;
    [super viewWillAppear:animated];
}

不要使用viewDidLoad 方法,而是使用viewWillAppear:animated:方法,該方法是在屏幕出現時候調用。

m文件中釋放方法

- (void)viewDidUnload {
    [super viewDidUnload];
    self.message = nil;
    self.label = nil;
}


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

7.5 第二個二級表控制器

wps_clip_image-23234

CheckListController.h

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

@interface CheckListController : SecondLevelViewController {
    NSArray *listData;
    NSIndexPath *lastIndexPath;
}

@property (nonatomic, retain) NSArray *listData;
@property (nonatomic, retain) NSIndexPath *lastIndexPath;

@end

CheckListController.m

 

- (void)viewDidLoad {
    NSArray *array = [[NSArray alloc] initWithObjects:@"Who Hash",
                      @"Bubba Gump Shrimp Étouffée", @"Who Pudding", @"Scooby Snacks",
                      @"Everlasting Gobstopper", @"Green Eggs and Ham", @"Soylent Green",
                      @"Hard Tack", @"Lembas Bread",  @"Roast Beast", @"Blancmange", nil];
    self.listData = array;
    [array release];
}


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

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

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

實現TableView數據源方法

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [listData count];
}

 

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSInteger row = [indexPath row];
//    NSInteger oldRow = [lastIndexPath row];
    
    cell.textLabel.text = [listData objectAtIndex:row];
//    cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? 
//            UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
   
    return cell;
}

 

實現TableView委托方法

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    int newRow = [indexPath row];
    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
    
    if (newRow != oldRow) {
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
        
        UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
        oldCell.accessoryType = UITableViewCellAccessoryNone;
        
        lastIndexPath = indexPath;
    }
    
}

 

int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;

獲得上次選擇的單元格行,如果lastIndexPath為nil這設置為-1

newCell.accessoryType = UITableViewCellAccessoryCheckmark;

設置新單元格為UITableViewCellAccessoryCheckmark oldCell.accessoryType = UITableViewCellAccessoryNone;

設置舊單元格為UITableViewCellAccessoryNone

RootViewController中 viewDidLoad方法

    //增加check控制器
    CheckListController *checkListController = [[CheckListController alloc] 
                                                              initWithStyle:UITableViewStylePlain];
    
    checkListController.title = @"Check One";
    checkListController.rowImage = [UIImage imageNamed:@"checkmarkControllerIcon.png"];
    [array addObject:checkListController];
    [checkListController release];

 

7.6 第三個二級表控制器

wps_clip_image-18138

RowControlsController.h

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

@interface RowControlsController : SecondLevelViewController {
    NSArray *listData;
}

@property (nonatomic, retain) NSArray *listData;
-(IBAction)buttonTapped:(id)sender;

@end

 

RowControlsController.m

@implementation RowControlsController

@synthesize listData;

-(IBAction)buttonTapped:(id)sender {
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    
    NSInteger buttonRow = [[self.tableView indexPathForCell:buttonCell] row];
    NSString *rowTitle = [listData objectAtIndex:buttonRow];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"點擊Button" 
                                        message:[NSString stringWithFormat:@"你點擊的Button是 %@",rowTitle]
                                        delegate:self 
                                        cancelButtonTitle:@"Ok" 
                                        otherButtonTitles:nil];
    [alert show];
    [alert release];
}

- (void)viewDidLoad {
    NSArray *array = [[NSArray alloc] initWithObjects:@"R2-D2",
                      @"C3PO", @"Tik-Tok", @"Robby", @"Rosie", @"Uniblab",
                      @"Bender", @"Marvin", @"Lt. Commander Data", 
                      @"Evil Brother Lore", @"Optimus Prime", @"Tobor", @"HAL", 
                      @"Orgasmatron", nil];
    self.listData = array;
    [array release];
}


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

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

 

實現TableView數據源方法

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [listData count];
}

 

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
        
        UIImage *buttonUpImage = [UIImage imageNamed:@"button_up.png"];
        UIImage *buttonDownImage = [UIImage imageNamed:@"button_down.png"];
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0.0f, 0.0f, buttonUpImage.size.width, buttonUpImage.size.height);
        [button setBackgroundImage:buttonUpImage forState:UIControlStateNormal];
        [button setBackgroundImage:buttonDownImage forState:UIControlStateHighlighted];
        [button setTitle:@"Tap" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
        
        cell.accessoryView = button;
    }

    NSInteger row = [indexPath row];
    NSString *rowTitle = [listData objectAtIndex:row];
    cell.textLabel.text = rowTitle;
    
    return cell;
}

 

由於我們沒有nib文件,所以按鈕要通過代碼自己寫按鈕, 如下:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

指定按鈕的邊框大小:

button.frame = CGRectMake(0.0f, 0.0f, buttonUpImage.size.width, buttonUpImage.size.height);

設定按鈕正常狀態時候背景圖片

[button setBackgroundImage:buttonUpImage forState:UIControlStateNormal];

設定按鈕高亮狀態時候背景圖片

[button setBackgroundImage:buttonDownImage forState:UIControlStateHighlighted];

button setTitle:@"Tap" forState:UIControlStateNormal 設置按鈕正常狀態時候的title內容。

[button addTarget:self action:@selector(buttonTapped:)   forControlEvents:UIControlEventTouchUpInside];

由於沒有nib文件按鈕事件不能通過IB設計工具添加,要通過代碼實現與按鈕事件的處理。

cell.accessoryView = button;

把按鈕對象賦給單元格的accessoryView(擴展視圖)。

wps_clip_image-14518

實現TableView委托方法

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSInteger buttonRow = [indexPath row];
    NSString *rowTitle = [listData objectAtIndex:buttonRow];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"點擊Row" 
                                        message:[NSString stringWithFormat:@"你點擊的Row是 %@",rowTitle]
                                        delegate:self 
                                        cancelButtonTitle:@"Ok" 
                                        otherButtonTitles:nil];
    [alert show];
    [alert release];
    
}

 

RowControlsController.m

-(IBAction)buttonTapped:(id)sender {
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    
    NSInteger buttonRow = [[self.tableView indexPathForCell:buttonCell] row];
    NSString *rowTitle = [listData objectAtIndex:buttonRow];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"點擊Button" 
                                        message:[NSString stringWithFormat:@"你點擊的Button是 %@",rowTitle]
                                        delegate:self 
                                        cancelButtonTitle:@"Ok" 
                                        otherButtonTitles:nil];
    [alert show];
    [alert release];
}

- (void)viewDidLoad {
    NSArray *array = [[NSArray alloc] initWithObjects:@"R2-D2",
                      @"C3PO", @"Tik-Tok", @"Robby", @"Rosie", @"Uniblab",
                      @"Bender", @"Marvin", @"Lt. Commander Data", 
                      @"Evil Brother Lore", @"Optimus Prime", @"Tobor", @"HAL", 
                      @"Orgasmatron", nil];
    self.listData = array;
    [array release];
}

 

buttonTapped:方法,是點擊單元格中的按鈕觸發事件。

UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];

其中superview獲得父控件,即表視圖單元格。

NSInteger buttonRow = [[self.tableView indexPathForCell:buttonCell] row];

其中獲得選擇的單元格中的按鈕所在的單元格行數。

RootViewController中 viewDidLoad方法

    //增加Row控制器
    RowControlsController *rowControlsController = [[RowControlsController alloc] 
                                                initWithStyle:UITableViewStylePlain];
    
    rowControlsController.title = @"Row Controls";
    rowControlsController.rowImage = [UIImage imageNamed:@"rowControlsIcon.png"];
    [array addObject:rowControlsController];
    [rowControlsController release];

 

7.7 第四個二級表控制器

wps_clip_image-10611

MoveMeController.h

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

@interface MoveMeController : SecondLevelViewController {
    NSMutableArray *listData;
}
@property (nonatomic, retain) NSMutableArray *listData;
-(IBAction)toggleMove;

@end

 

MoveMeController.m

@implementation MoveMeController

@synthesize listData;

-(IBAction)toggleMove {
    
    [self.tableView setEditing:!self.tableView.editing animated:YES];
    
    if (self.tableView.editing) {
        [self.navigationItem.rightBarButtonItem setTitle:@"Done"];
    } else {
        [self.navigationItem.rightBarButtonItem setTitle:@"Move"];
    }
    
}
#pragma mark -
#pragma mark Memory management

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

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


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

 

 
toggleMove方法,是點擊導航控制器右邊按鈕時候觸發事件,如果表單元格處於編輯狀態時候,設為不可編輯,反之可以編輯單元格。

MoveMeController.m

#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {
    if (listData == nil) {
        NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:
                             @"Eeny", @"Meeny", @"Miney", @"Moe", @"Catch", @"A", 
                             @"Tiger", @"By", @"The", @"Toe", nil];
        self.listData = array;
        [array release];   
    }
    
    UIBarButtonItem *moveButton = [[UIBarButtonItem alloc] 
                                   initWithTitle:@"Move" 
                                   style:UIBarButtonItemStyleBordered 
                                   target:self 
                                   action:@selector(toggleMove)];
    self.navigationItem.rightBarButtonItem = moveButton;
    [moveButton release];
    [super viewDidLoad];
}

 

實現TableView數據源方法

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [listData count];
}

 

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
        //cell.showsReorderControl = YES;
    }
    NSInteger row = [indexPath row];
    cell.textLabel.text = [listData objectAtIndex:row];
    
    return cell;
}

 

// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView 
      moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
      toIndexPath:(NSIndexPath *)toIndexPath {
    
    NSInteger fromRow = [fromIndexPath row];
    NSInteger toRow = [toIndexPath row];
    
    id object = [listData objectAtIndex:fromRow];//[[listData objectAtIndex:fromRow] retain];
    [listData removeObjectAtIndex:fromRow];
    [listData insertObject:object atIndex:toRow];
    
    //[object release];
    
}

 

// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}

 

控制單元格行是否可以移動,本例中我們是可以移動所有行。

實現TableView委托方法

#pragma mark -
#pragma mark Table view delegate

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView 
           editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleNone;
}

 

我們希望能夠對行重新排序,不過不希望用戶能夠刪除或插入行,因此,我們實現了上面的委托方法,通過這個方法,表視圖可以詢問指定的行是否可以被刪除,或是否可以將新行插入到指定的位置。通過為每一行返回

UITableViewCellEditingStyleNone,表示我們不支持插入或刪除任何行。

RootViewController中 viewDidLoad方法

    //增加Move控制器
    MoveMeController *moveMeController = [[MoveMeController alloc] 
                                                    initWithStyle:UITableViewStylePlain];
    
    moveMeController.title = @"Move Me";
    moveMeController.rowImage = [UIImage imageNamed:@"moveMeIcon.png"];
    [array addObject:moveMeController];
    [moveMeController release];

 

7.8 第五個二級表視圖控制器

wps_clip_image-12615

DeleteMeController.h

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

@interface DeleteMeController : SecondLevelViewController {
    NSMutableArray *listData;
}

@property (nonatomic, retain) NSMutableArray *listData;
-(IBAction)toggleMove;

@end

 

DeleteMeController.m

@implementation DeleteMeController

@synthesize listData;

-(IBAction)toggleMove {
    
    [self.tableView setEditing:!self.tableView.editing animated:YES];
    
    if (self.tableView.editing) {
        [self.navigationItem.rightBarButtonItem setTitle:@"Done"];
    } else {
        [self.navigationItem.rightBarButtonItem setTitle:@"Move"];
    }
    
}


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

 

toggleMove方法,是點擊導航控制器右邊按鈕時候觸發事件,如果表單元格處於編輯狀態時候,設為不可編輯,反之可以編輯單元格。

DeleteMeController.m

- (void)viewDidLoad {
    
    if (listData == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"computers" ofType:@"plist"];
        NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
        
        self.listData = array;
        [array release];
    }
    
    UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:@"Delete" 
                                                style:UIBarButtonItemStyleBordered 
                                                target:self 
                                                action:@selector(toggleMove)];
    self.navigationItem.rightBarButtonItem = editButton;
    [editButton release];
}

 

實現TableView數據源方法

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [listData count];
}

 

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSInteger row = [indexPath row];
    cell.textLabel.text = [listData objectAtIndex:row];
    
    return cell;
}

 

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSInteger row = [indexPath row];
        [self.listData removeObjectAtIndex:row];
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }
    
}

 

-(void)tableView:(UITableView *)tableView commitEditingStyle:

(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

該委托方法是實現刪除和插入功能。

RootViewController中 viewDidLoad方法

    //增加Delete控制器
    DeleteMeController *deleteMeController = [[DeleteMeController alloc] 
                                          initWithStyle:UITableViewStylePlain];
    
    deleteMeController.title = @"Delete Me";
    deleteMeController.rowImage = [UIImage imageNamed:@"deleteMeIcon.png"];
    [array addObject:deleteMeController];
    [deleteMeController release];

 

7.9 第六個二級表視圖控制器

wps_clip_image-22580

TeamsViewController.h

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

@interface TeamsViewController : SecondLevelViewController {
    NSArray *listData;
}

@property (nonatomic, retain) NSArray *listData;

@end

 

TeamsViewController.m

#import "TeamsViewController.h"
#import "TeamsViewController.h"
#import "TeamsDetailController.h"

@implementation TeamsViewController
@synthesize listData;
- (void)viewDidLoad {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"teamdictionary" ofType:@"plist"];
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    self.listData =  [dict allKeys];
    [dict release];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
    self.listData = nil;
}
- (void)dealloc {
    [listData release];
    [super dealloc];
}

 

實現TableView數據源方法

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [listData count];
}

 

實現TableView數據源方法

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    NSInteger row = [indexPath row];
    NSString *title = [listData objectAtIndex:row];
    cell.textLabel.text = title;
    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSInteger row = [indexPath row];
    NSString *groupName = [listData objectAtIndex:row];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"teamdictionary" ofType:@"plist"];
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    
    TeamsDetailController *detailController = [[TeamsDetailController alloc]
                                                    initWithStyle:UITableViewStyleGrouped];
    
    detailController.listData = [dict objectForKey:groupName];    
    [dict release];
    
    //[array release];
    // Navigation logic may go here. Create and push another view controller.
     [self.navigationController pushViewController:detailController animated:YES];
     [detailController release];
}

可編輯表視圖控制器

wps_clip_image-12993

TeamsDetailController.h

#import <UIKit/UIKit.h>
#define TEAM1  1
#define TEAM2  2
#define TEAM3  3
#define TEAM4  4
#define LABLE_TAG 45678

@interface TeamsDetailController : UITableViewController <UITextFieldDelegate> {
    NSArray *listData;
    NSMutableArray *teamsData;
    NSArray *fieldLables;
}

@property (nonatomic, retain) NSArray *listData;
@property (nonatomic, retain) NSArray *fieldLables;
@property (nonatomic, retain) NSMutableArray *teamsData;

-(IBAction)cancel:(id)sender;
-(IBAction)save:(id)sender;
-(IBAction)textFieldDone:(id)sender;

@end

 

TeamsDetailController.m

#import "TeamsDetailController.h"


@implementation TeamsDetailController

@synthesize listData;
@synthesize fieldLables;
@synthesize teamsData;

-(IBAction)cancel:(id)sender {
    [self.navigationController popViewControllerAnimated:YES];
}

-(IBAction)save:(id)sender {
    
    for (UIView *oneView in self.tableView.subviews) {
        if ([oneView isMemberOfClass:[UITableViewCell class]]) {
            UITableViewCell *cell = (UITableViewCell *)oneView;
            for (UIView *twoView in cell.contentView.subviews) {
                if ([twoView isMemberOfClass:[UITextField class]]) {
                    UITextField *textField = (UITextField *)twoView;
                    NSLog(@"行 %i -- value %@", textField.tag ,textField.text);
                }
            }
        }
    }
    
    [self.navigationController popViewControllerAnimated:YES];
    
}

 

-(IBAction)textFieldDone:(id)sender {
    [sender resignFirstResponder];    
}

- (void)viewDidUnload {
    self.listData = nil;
    self.teamsData = nil;
    self.fieldLables = nil;
    self.listData = nil;
}

- (void)dealloc {
    [listData release];
    [teamsData release];
    [fieldLables release];
    [super dealloc];
}

 

- (void)viewDidLoad {
    teamsData = [[NSMutableArray alloc] init];
    for (id name in listData) {
        [teamsData addObject:name];
    }
    
    NSArray *array = [[NSArray alloc] initWithObjects:@"第一隊:",@"第二隊:",@"第三隊:",@"第四隊:", nil];
    self.fieldLables = array;
    [array release];
    
    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] 
                                    initWithTitle:@"Cancel" 
                                    style:UIBarButtonItemStyleBordered 
                                    target:self 
                                    action:@selector(cancel:)];
    self.navigationItem.leftBarButtonItem = cancelButton;
    [cancelButton release];
    
    UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] 
                                     initWithTitle:@"Save" 
                                     style:UIBarButtonItemStyleBordered 
                                     target:self 
                                     action:@selector(save:)];
    self.navigationItem.rightBarButtonItem = saveButton;
    [saveButton release];    
}

- (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.
}

 

實現TableView數據源方法

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [teamsData count];
}

 

 

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 75, 25)];
        label.textAlignment = UITextAlignmentRight;
        label.tag = LABLE_TAG;
        label.font = [UIFont boldSystemFontOfSize:14];
        [cell.contentView addSubview:label];
        
        [label release];
        
        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(90, 12, 200, 25)];
        textField.clearsOnBeginEditing = NO;
        [textField setDelegate:self];
        textField.returnKeyType = UIReturnKeyDone;
        [textField addTarget:self action:@selector(textFieldDone:) forControlEvents:UIControlEventEditingDidEndOnExit];
        
        [cell.contentView addSubview:textField];
        
        [textField release];
        
    }
    
    NSInteger row = [indexPath row];
    
    UILabel *label = (UILabel *)[cell viewWithTag:LABLE_TAG];
    UITextField *textField = nil;
    for (UIView *oneView in cell.contentView.subviews) {
        if ([oneView isMemberOfClass:[UITextField class]]) {
            textField = (UITextField *)oneView;
        }
    }

    label.text = [fieldLables objectAtIndex:row];
    textField.text = [listData objectAtIndex:row];
    textField.tag = row;
    
    return cell;
}

 

實現TableView委托方法

#pragma mark 文本字段控件的委托方法 
- (void)textFieldDidEndEditing:(UITextField *)textField {
    NSLog(@"修改 行 %i -- value %@", textField.tag ,textField.text);
}

 

RootViewController中 viewDidLoad方法

    //增加可編輯詳細窗格控制器
    TeamsViewController *teamsViewController = [[TeamsViewController alloc] 
                                              initWithStyle:UITableViewStylePlain];
    
    teamsViewController.title = @"Detail Edit";
    teamsViewController.rowImage = [UIImage imageNamed:@"detailEditIcon.png"];
    [array addObject:teamsViewController];
    [teamsViewController release];

 

 

注:
1 本教程是基於關東升老師的教程
2 基於黑蘋果10.6.8和xcode4.2
3 本人初學,有什么不對的望指教
4 教程會隨着本人學習,持續更新
5 教程是本人從word筆記中拷貝出來了,所以格式請見諒


免責聲明!

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



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