IPhone SDK: Using Table Views

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 or Apple Key + Shft + N to bring up the new project menu. Select the Applications 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





















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值