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笔记中拷贝出来了,所以格式请见谅

转载于:https://www.cnblogs.com/syxchina/archive/2012/09/12/2681101.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gin redis 链接不上_Redis 高并发问题,及解决方案!

&#xff08;一&#xff09;redis技术的使用&#xff1a;redis真的是一个很好的技术&#xff0c;它可以很好的在一定程度上解决网站一瞬间的并发量&#xff0c;例如商品抢购秒杀等活动。。。redis之所以能解决高并发的原因是它可以直接访问内存&#xff0c;而以往我们用的是数据…

任务管理平台_软件品质评测系统任务分发管理平台

testkuaibao|软件测试自学公众号1●为什么需要任务分发平台●在一个基本的评测系统中我们有了评测执行工具、评测数据、评测环境就能进行一次评测任务的执行&#xff0c;但现在是大数据时代&#xff0c;我们更多的需求是针对大量数据进行评测。比如在输入法评测中我们有10000个…

[转载]Visual Studio 2010敏捷利剑:详解Scrum

Visual Studio 2010敏捷利剑:详解Scrum 【IT168 专稿】随着微软Visual Studio 2010 Ultimate Beta2版本的发布&#xff0c;除了它提供协同一致的ALM(应用程序生命周期)管理工具外&#xff0c;MSF for Agile Software Development过程框架从4.2升级到5.0&#xff0c;并且是以Scr…

网站收录工具(php导航自动收录源码)_10步把企业网站优化做到极致,SEO优化的核心知识...

对于企业网站优化&#xff0c;重要的就3点&#xff0c;内容原创、外链建设、内部优化&#xff0c;其它网站优化也会涉及到这些&#xff0c;但是企业站就变的简单的多了&#xff0c;下面10步让你把企业网站优化做到极致。第一步&#xff1a;首先域就是让搜索引擎选择我们网站的主…

mysql not is null_转!!mysql 字段 is not null 和 字段 !=null

今天在查询数据时&#xff0c;查到包含一条某个时间startTime(该字段默认为null ) 为null的记录&#xff0c;想把它过滤&#xff0c;加了 startTime! null 的条件&#xff0c;结果记录都没了&#xff0c;应该用条件 is not null。转自&#xff1a;https://segmentfault.com/a/1…

myeclipse mysql连接_MyEclipse连接Mysql数据库的方法(一)

准备工作&#xff1a;MyEclipse使用的是2013版&#xff0c;mysql Ver 14.14 Distrib 5.6.281.jar包的下载(jdbc驱动)我下载的是&#xff1a;mysql-connector-java-5.1.7-bin.jar2.打开MyEclipse---->选择window---->选择open perspecctive---->myeclipse Database Exp…

c malloc 头文件_C/C++笔试题:主要考察C/C++语言基础概念算法及编程,附参考答案...

1.编写my_strcpy函数&#xff0c;实现与库函数strcpy类似的功能&#xff0c;不能使用任何库函数&#xff1b;答&#xff1a;char *strcpy(char *strDest, const char *strSrc){if ( strDest NULL || strSrc NULL)return NULL ;if ( strDest strSrc)returnstrDest ;char *tem…

SQLlite数据导入到mySQL_如何批量导入数据到Sqlite数据库

做android和ios开发的一般都用Sqlite数据库&#xff0c;有的时候数据需要批量导入&#xff0c;那么如何导入呢&#xff1f;在这里&#xff0c;介绍2种方法供大家参考。一、用sqlite命令以windows系统为例&#xff0c;linux下命令是一样的。1.安装sqlite工具包首先要安装有sqlit…

c/c++ 运行库

11.2 C/C运行库 11.2.1 C语言运行库 任何一个C程序&#xff0c;它的背后都有一套庞大的代码来进行支撑&#xff0c;以使得该程序能够正常运行。这套代码至少包括入口函数&#xff0c;及其所依赖的函数所构成的函数集合。当然&#xff0c;它还理应包括各种标准库函数的实现。…

下面哪个字段是http请求中必须具备的_理解HTTP协议-HTTP协议详解总结

一、HTTP协议的演进HTTP(HyperText Transfer Protocol)协议是基于TCP的应用层协议&#xff0c;它不关心数据传输的细节&#xff0c;主要是用来规定客户端和服务端的数据传输格式&#xff0c;最初是用来向客户端传输HTML页面的内容。默认端口是80。1、HTTP 0.9版本 1991年这个版…

ad电阻原理图_负载电阻的原理及应用

在开始主题之前&#xff0c;我们需要了解的是&#xff1a;负载电阻是什么&#xff1f;将其拆分&#xff1a;负载和电阻&#xff1b;负载&#xff0c;顾名思义&#xff0c;是指连接在电路中的电源两端的电子元件。主要功能就是将电能转换成其他形式的能&#xff0c;以实现能量的…

python dataframe 新列_Python第二十四课:Pandas库(四)

Python第二十四课&#xff1a;Pandas库(四)点击上方“蓝字”&#xff0c;关注我们.不知不觉&#xff0c;我们已经跨越了千难万险&#xff0c;从零开始&#xff0c;一步步揭开了Python神秘的面纱。学到至今&#xff0c;回过头&#xff0c;才晓得自己在不知不觉已经学会了如此多的…

hashmap 遍历_别慌,送你21 个面试官必问HashMap考点

Java面试笔试面经、Java技术每天学习一点Java面试关注不迷路作者&#xff1a;菜鸟小于来源&#xff1a;https://www.cnblogs.com/Young111/p/11519952.html1&#xff1a;HashMap 的数据结构&#xff1f;A&#xff1a;哈希表结构(链表散列&#xff1a;数组链表)实现&#xff0c;…

22套精美的网页按钮图标设计推荐(包括PSD和AI文件)

图标是一个简单的单色符号&#xff0c;表示对象的基本形状。字形被广泛地使用在我们周围的公共场所&#xff0c;如机场和商场或购物中心。在网页设计当中&#xff0c;他经常会被使用&#xff0c;用来展示每个元素代表的意思&#xff0c;他简洁大方&#xff0c;一目了然&#xf…

轻gc和重gc分别在什么时候发生_GC发展与现状

GC发展Java不像C或C那样&#xff0c;需要程序员在编程的过程中&#xff0c;时刻注意申请内存保存对象&#xff0c;在对象使用完成后&#xff0c;要在合适的时机将对象占用的内存释放掉(析构函数)&#xff1b;Java得意与内部的三大机制&#xff0c;保证了程序开发方便&#xff1…

nginx离线安装_web高可用-基于keepalived和nginx

一&#xff0e;体系架构在Keepalived Nginx高可用负载均衡架构中&#xff0c;keepalived负责实现High-availability (HA) 功能控制前端机VIP(虚拟网络地址)&#xff0c;当有设备发生故障时&#xff0c;热备服务器可以瞬间将VIP自动切换过来&#xff0c;实际运行中体验只有2秒钟…

php mysql 实现原理_php+mysql分页原理实现

完整代码如下&#xff1a;!htmlhead-"-type"";GBK"styletype"text/css"body{font-size:12px;font-family:verdana;width:100%;}div.page{text-align:center;}div.content{height:300px;}div.pagea{border:#aaaadd1pxsolid;text-decoration:none;…

python任意代码都可以缩进去_我发现了个 Python 黑魔法,执行任意代码都会自动念上一段 『平安经』...

最近的"平安经"可谓是引起了不小的风波啊。作为一个正儿八经的程序员&#xff0c;最害怕的就是自己的代码上线出现各种各样的 BUG。为此&#xff0c;明哥今天分享一个 Python 的黑魔法&#xff0c;教你如何在你执行任意 Python 代码前&#xff0c;让 Python 解释器自…

域用户更改密码提示拒绝访问_AD域中的ACL攻防探索

前言关于域内ACL的攻防近两年经常被人所提起&#xff0c;同时也产生了很多关于域内ACL相关的工具和攻击方式&#xff0c;本文将会从ACL的概念谈起&#xff0c;然后介绍几种不同的域内攻击方式以及如何监测和防御对于ACL的攻击。ACL的概念和作用ACM&#xff1a;首先想要了解ACL首…

go MySQL 多语句_八、MySQL经典查询语句-Go语言中文社区

student表course表score表teacher表1、 查询Student表中的所有记录的Sname、Ssex和Class列。select Sname,Ssex,Class from Student;2、 查询教师所有的单位即不重复的Depart列。select distinct Depart from Teacher3、 查询Student表的所有记录。select * from Student4、 查…