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

  • 相关阅读:
    PHP防盗链的基本思想&&防盗链的设置方法
    PHP程序员遇到职业问题时,是离职?还是坚持?
    如何学习Linux性能优化?
    PHP到底有多牛?你所知道的网站都在用它
    Linux 与 Unix 到底有什么不同?区别在哪?
    用PHP打造一个高性能好用的网站
    七夕-心形表白-简单css代码
    css雪碧图-css精灵图
    jquery-时间轴滑动
    js-进度条-动画
  • 原文地址:https://www.cnblogs.com/syxchina/p/2681101.html
Copyright © 2020-2023  润新知