现在的位置: 首页 > 综合 > 正文

IPhone SDK: Using Table Views

2013年09月11日 ⁄ 综合 ⁄ 共 11642字 ⁄ 字号 评论关闭
文章目录

IPhone SDK: Using Table Views

Using the table view control

This is a follow-up to my earlier tutorial "IPhone SDK HelloWorld" and covers the use of a Table View similar to the one used by the IPod app to display playlists. As before I will be using the 2.0 SDK so some features may not be available in the earlier version.


Step 1: Read the Hello World tutorial

If you are are unfamiliar with developing in Objective C and IPhone SDK please take a moment to go through the earlier tutorial IPhone SDK Hello World. It also contains instructions on how to install XCode and the IPhone SDK.

Step 2: Create a project

  SelectFile > New Project orApple Key + Shft + N to bring up the new project menu. Select theApplications item of the IPhone OS section from the menu on the left, and select View Based Application from the icons on the right. When prompted enter a project name, I have used TableView in the sample code. 

There are four files in the Classespackage; 
TableViewTutorialAppDelegate.h
TableViewTutorialAppDelegate.m
TableViewTutorialViewController.h
TableViewTutorialViewController.m

Step 2: Create the Data Controller Class

In addition to the four files generated automatically we need to create a new class (and hence assosiated header and source files) to store the data to be displayed in the view. Select File > New File or press the the Command Key + N to open the New File Dialog. Create a new source file of type NSObject Subclass (I used the name DataController.m) and make sure you select the checkbox labeled Also create "DataController.h" file (This will be different based on the name you gave your source file). 

In the DataController.h file add an instance of NSMutableArray to store actual data and also add helper methods to return size of array, item at a particular index and to add and delete items. Also add a property corresponding to the list to allow access. The complete file should look something like this:

1    #import <UIKit/UIKit.h>
2    @interface DataController : NSObject 
3    {
4        NSMutableArray *list;
5    }
6    - (unsigned)countOfList; //returns number of elements in list
7    - (id)objectInListAtIndex:(unsigned)theIndex; //returns object at given index
8    - (void)addData:(NSString*)data; //adds data to the list 
9    - (void)removeDataAtIndex:(unsigned)theIndex;
10   @property (nonatomic, copy, readwrite) NSMutableArray *list;
11   @end  

Step 2 b: Implement methods of Data Controller

First synthesize the getters and setters for the list proporty by adding @synthesize to after line 11 in DataController.m. Now implement the methods defined in the header file.  

Method: countOfList

The simplest method is the list count, just call the count method on the list property and return the result. 
1    - (unsigned)countOfList 
2    {
3        return [list count];
4    }

Method: objectInListAtIndex

Next and just as simple is to return the element at a specific index of the list just call the objectInListAtIndex method of the list and return the result. 
 
1    - (id)objectInListAtIndex:(unsigned)theIndex 
2    {
3        return [list objectAtIndex:theIndex];
4    }

Method: removeDataAtIndex

Just add the call to the list structure.

1    - (void)removeDataAtIndex:(unsigned)theIndex
2    {
3        [list    removeObjectAtIndex:theIndex];
4    }

Method: addData

I am currently using an NSString to store data but you probably want to create a domain object in a real program. 

1    - (void)addData:(NSString*)data;
2    {
3        [list addObject:data];
4    }

Method: setList

We also override the set list method to make sure the mutable array remains mutable.

1    // Custom set accessor to ensure the new list is mutable
2    - (void)setList:(NSMutableArray *)newList 
3    {
4        if (list != newList) 
5        {
6           [list release];
7           list = [newList mutableCopy];
8        }
9    }

  

Method: Init and dealloc

Used to initilize the objects and free mermory respectively. 

1    - (id)init 
2    {
3        if (self = [super init]) 
4        {
5            //Instantiate list
6            NSMutableArray *localList = [[NSMutableArray alloc] init];
7            self.list = localList;
8            [localList release];
9
10          //Add initial Data
11          [self addData:@"Item 1"];
12         [self addData:@"Item 2"];
13      }
14      return self;
15  }

1    - (void)dealloc 
2    {
3        [list release];
4        [super dealloc];
5    }

Step 3: Update Table View Controller

 
Currently the TableViewTutorialViewController inherits from the UIViewController class we need to change this to the UITableViewController. Moreover we need to add a data controller class to supply data to be displayed in the rows of the table view. For this we will add the @class declarative to our view controller header file and also create an instance of this data view class and add a property for that instance. In addition we also create a view to store the tableview and create a corresponding property. The code for TableViewTutorialViewController.h should look something like this:

1    #import <UIKit/UIKit.h>

2    @class DataController;
3    @interface TableViewTutorialViewController : UITableViewController 
4    {
5        DataController *dataController;
6        UIView * myView;
7    }
8
9    @property (nonatomic, retain) DataController *dataController;
10  @property (nonatomic, retain) UIView * myView;
11  @end 

Step 4: Implement Table View Controller Class

The code for the of TableViewTutorialViewController.m file is shown below I will individually explain the purpose of individual lines or groups of lines . Broadly what we are doing is drawing the interface (See initWithStyle and loadView), connecting it to this controller object (See loadView line 24 and 25) and then implementing the callbacks and event handlers. (See all other mehods)

//Line 1 should already exist in the auto generated file but add line to because we are going to be using methods
//from the data controller class.
1    #import "TableViewTutorialViewController.h"
2    #import "DataController.h"

//Line 3 is auto generated but we add lines 4 nd 5 to create getters and setters for the corresponding attributes
3    @implementation TableViewTutorialViewController
4    @synthesize dataController;
5    @synthesize myView;

Method: initWithStyle

//Constructor Equivelent: used to initilize view controller (self) and data controler
6    - (id)initWithStyle:(UITableViewStyle)style 
7    {
8        if (self = [super initWithStyle:style]) 
9       {
10           self.dataController = [[DataController alloc] init];
11     }
12
13     return self;
14  }

Method: loadView

//Define the interface and connect to controller object by specifying self as delegate and data source
 
15   -(void)loadView
16   {    
17        // create and configure the view
18       CGRect cgRct = CGRectMake(0, 10, 320, 400); //define size and position of view 
19        myView = [[UIView alloc] initWithFrame:cgRct]; //initilize the view    
20        myView.autoresizesSubviews = YES;              //allow it to tweak size of elements in view 
21       self.view = myView;                            //set view property of controller to the newly created view    
22       UITableView * tableView = [[UITableView alloc] initWithFrame:cgRct style:UITableViewStylePlain];
23       tableView.editing = YES;  //This allows user of progrm to add or remove elements from list
24       tableView.dataSource = self;
25       tableView.delegate = self; //make the current object the event handler for view
26          
27       [self.view addSubview:tableView];
28   }

Method: numberOfSectionsInTableView

//We have to implement this as the object is the data source for the table view
//Hard coded number of sections in table to 1 as we are only making a single list for this example  
29   - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
30   {
31       return 1;
32   }

Method: numberOfRowsInSection

//We have only one section and that section has a single datasource so we just return the number of elements in 
//the datasource. We have the plus one because we want to add a speacial item at the top of the list which allows //us to add more items to the list. We see how that is done later  

33   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
34   {
35       // Only one section so return the number of items in the list
36       return [dataController countOfList]+1;
37   }

Method: cellForRowAtIndexPath

//This is a call back invoked by the interface when drawing the table view. This method will create a cell for each 
// row and add text to each cell dependeing on the string retrieved from the datasource. Note this is called for each 
/index from zero to the number or rows returned by the previous method (numberOfRowsInSection). The zeroth 
//row is hard coded to display the text "New Item" this is used to add new rows to the table.

38   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
39   {
            //Try to get rusable cell
40        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
41        if (cell == nil) 
42        {
                  //If not possible create a new cell
43              cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0,0,0,0) reuseIdentifier:@"CellIdentifier"] 
                            autorelease];
44              cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
45        }
    
46        // Get the string to display and set the value in the cell
47        if(indexPath.row == 0)
48        {
                //The first (or zeroth cell) contains a New Item string and is used to add elements to list
49            cell.text  = @"New Item...";
50        }
51        else
52        {
                //Retreive text from datasource, the -1 accounts for the first element being hardcoded to say new Item
53            cell.text = [dataController objectInListAtIndex:indexPath.row-1];
54        }
55        return cell;
56   }

Method: editingStyleForRowAtIndexPath

//This defines for each row its editing style, i.e. whether it shows a remove sign (Red circle with subtract sign) or 
//and add sign (Green circle with addition sign). I have hard coded the first row (the one that says "New Item") to display the add sign and all others to display the subtract sign. 

57   - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:
            (NSIndexPath *)indexPath
58   {
59       if(indexPath.row == 0)
60       {
61           return UITableViewCellEditingStyleInsert;
62       }
63       else
64       {
65           return UITableViewCellEditingStyleDelete;
66       }
67   }

Method: commitEditingStyle

//This method is invoked when the user has finished editing one of the rows of the table. The three parameters
//respectivly proivide, the table being edited, the style of the row being edited (Add or Delete) and the row being 
//edited. If the style is delete we remove the corresponding item from the data source and then delete the row from 
///the view. If the style was add we add another element to the data source and relode the data into the table view.
//In reality add item will probably load a new view which allows the user to enter text but that is left to another 
//tutorial for now we are hard coding the text to be added.   

68   - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
            forRowAtIndexPath:(NSIndexPath *)indexPath 
69   {
70       // If row is deleted, remove it from the list.
71       if (editingStyle == UITableViewCellEditingStyleDelete) 
72       {
73           [dataController removeDataAtIndex:indexPath.row-1];
74           [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
                    withRowAnimation:UITableViewRowAnimationFade];
75       }
76       else if(editingStyle == UITableViewCellEditingStyleInsert)
77       {
78           [dataController addData:@"New Row Added"];
79           [tableView reloadData];        
80       }
81   }

82   - (void)dealloc 
83   {
84       [super dealloc];
85  }

86   @end

Step 5: Loading the TableView

In the TableViewTutorialAppDelegate.m file's applicationDidFinishLaunching method initialize the tableview controller and add it as a sub view. The code should look something like this.

1    - (void)applicationDidFinishLaunching:(UIApplication *)application
2    {    
3        viewController = [[TableViewTutorialViewController alloc]                             initWithStyle:UITableViewStylePlain];
5        [window addSubview:viewController.view];
6        [window makeKeyAndVisible];
7    }
 

Step 6: Try it out

This the interface you should see when you run your code. Click on the Red remove sign and you will see a delete button 

Clicking on the delete button should remove the corresponding row from the table, see below.

Now click the green add button and a new row should appear as mentioned earlier currently the text if the new button has been hard coded. 

I hope this tutorial was clear and helpful let me know if there are any problems or if it can be improved. Also please download the XCode project from my site Here

抱歉!评论已关闭.