转载自:

在网上搜索了一下, 介绍UITableView分页的文章不少, 而且都很统一, 代码也都正确. 只是没有把思路给整理出来. 我这里借花献佛, 整理一下.

这里假定的前提是, 你已经将UITableView添加到了View中, 并且在h文件中实现了 UITableViewDelegate,UITableViewDataSource 这两个接口, 且已经与你后台定义的tblView建立起了关联, UITableView的datesource和delegete也都已经指向了file's owner.

如果此处不太明白的话, 建议还是复习一下如何使用UITableView, 再来研究这部份.

1. 首先需要做的是, 定义数据源. UITableView是需要一个数据源的, 我这用使用的是SQLITE数据库, 因此做了一个小小的分页查询. SQLIte的分页查询与MySQL的相同.


[sql] 
view plain 
copy 
 
1.  select * from table where 列名 = 条件 limit 页数 * 每页显示记录数, 每页显示记录数  
[cpp] 
view plain 
copy 
 
1.  +(NSMutableArray *)GetRecord:(NSInteger)p  
2.  {   //代码中, 除了SQLITE的SELECT操作之外, 和分页有关系的就是参数p和下面分页的SQL语法拼接形式了.  
3.     NSString *query = [NSString stringWithFormat:@"select * from table order by ID limit %d,10", (p-1) * 10];  
4.     char *select =(char *)[query UTF8String];  
5.     NSMutableArray *array = [[NSMutableArray alloc] init];  
6.     sqlite3 *database;  
7.     if(sqlite3_open([DbObject GetDatabasePath], &database) == SQLITE_OK)  
8.     {  
9.         sqlite3_stmt *statement;  
10.         if(sqlite3_prepare_v2(database, select, -1, &statement, nil)== SQLITE_OK)  
11.         {  
12.             while (sqlite3_step(statement) == SQLITE_ROW)   
13.             {  
14.                  //根据字段的类似, 使用sqlite3_column_init, sqlite3_column_blob, sqlite3_column_text等将数据从记录行中取出来. 此处代码略  
15.                 //然后将出来的值,以键值对应的形式赋值给NSDictionary数组.  
16.                 NSDictionary *rowRecord = [[NSDictionary alloc] initWithObjectsAndKeys:nsID,@"ID", data, @"Image",  
17.                                            nsMessage, @"Message", nsVideoURL, @"VideoURL", nsAudioURL, @"AudioURL",   
18.                                            nsToLine, @"ToLine",nsSendDate,@"SendDate", nil];  
19.         //将NSDictionary添加到NSMuableArray数组中.  
20.                 [array addObject:rowRecord];  
21.         }  
22.         sqlite3_finalize(statement);   
23.     }  
24.     sqlite3_close(database);  
25.     }  
26.     return array;  
27.  }

当然了这个函数还要在你的h文件中声明, 然后才可以在m文件中implement,否则当你使用 [类名 函数名:参数] 访问时会找不到方法的.

 

2. 这下要进入我们的页面进行设计了.  首先要在页面的.h 文件中声明变量  NSInteger currentPage, 这个变量是用来告诉系统, 我现在是处于第几页.

[cpp] 
view plain 
copy 
 
1.  NSInteger currentPage;  
2.  @property(strong, nonatomic) IBOutlet NSMutableArray *listData;  
3.  @property(strong, nonatomic) IBOutlet UITableView *tbView;  
 3. 在系统初始化时, 将变量的值设置为1, 然后对UITableView对象使用到的数据源进行赋值.
 
[cpp] 
view plain 
copy 
 
1.  - (void)viewDidLoad  
2.  {  
3.     [super viewDidLoad];  
4.     // Do any additional setup after loading the view from its nib.  
5.     currentPage = 1;  
6.     listData = [DbMyClass GetRecord:currentPage];  
7.  }

4. 然后我们要做的就是处理UITableView了, 正常情况下, 我们在numOfRowsInSections的地方返回的是总记录数, 但是我们多加了行分页按钮, 因此返回的总记录数要加上1


[cpp] 
view plain 
copy 
 
1.  -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
2.  {  
3.     NSInteger row = [listData count];  
4.     return row +1;  
5.  }

5. 然后我们在 cellForRowAtIndexPath 中正常处理我们的单元格信息, 比如说我们使用了自定义单元格, 我们就要在这里加载...  这是最重要的一点是, 需要判断 [indexPath

row ] =和[ listData count ]的值是否相同, 如果相同, 那么就需要加载我们的分页按钮了.

[cpp] 
view plain 
copy 
 
1.  -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
2.  {  
3.     static NSString *CellTableIdentifier = @"CusCellFutureMessage";  
4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];  
5.     if(cell == nil)  
6.     {  
7.         if([indexPath row] == [listData count])  
8.         {  
9.             //新建一个单元格, 并且将其样式调整成我们需要的样子.  
10.             cell=[[UITableViewCell alloc] initWithFrame:CGRectZero   
11.                                          reuseIdentifier:@"LoadMoreIdentifier"];   
12.             cell.font = [UIFont boldSystemFontOfSize:13];    
13.             cell.textLabel.text = @"读取更多...";  
14.         }  
15.         else  
16.         {  
17.                //其它单元格的初始化事件. 自定义单元格的读取, 或者是单元格的设置等.  
18.         }  
19.     }  
20.     return cell;  
21.  }  

6. 然后就是注册UITableView被点击之后, 要触发的事件了. 事件需要在 didSelectRowAtIndexPath 中定义 
[cpp] 
view plain 
copy 
 
1.  -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
2.  {  
3.     if([indexPath row] == [listData count])  
4.     {  
5.         UITableViewCell *loadMoreCell=[tableView cellForRowAtIndexPath:indexPath];     
6.         loadMoreCell.textLabel.text=@"正在读取更信息 …";     
7.         [self performSelectorInBackground:@selector(loadMore) withObject:nil];     
8.         [tableView deselectRowAtIndexPath:indexPath animated:YES];     
9.         return;    
10.     }  
11.     else  
12.     {  
13.          //其它单元格的事件    
14.     }  
15.  }

7. 也许你注意到了, 在给单元格设置peformSelectorInBackground的时候, 我们调用了loadMore函数. 这个函数就是我们这里的第二核心的方法了.


[cpp] 
view plain 
copy 
 
1.  -(void)loadMore     
2.  {   //当你按下这个按钮的时候, 意味着你需要看下一页了, 因此当前页码加1  
3.     currentPage ++;  
4.     NSMutableArray *more = [DbMyClass GetRecord:currentPage]; //通过调用GetRecord方法, 将数据取出. 
5.     [self performSelectorOnMainThread:@selector(appendTableWith:) withObject:more waitUntilDone:NO];     
6.  }     
7.  -(void) appendTableWith:(NSMutableArray *)data     
8.  {   //将loadMore中的NSMutableArray添加到原来的数据源listData中.  
9.     for (int i=0;i<[data count];i++) {     
10.         [listData addObject:[data objectAtIndex:i]];     
11.     }     
12.     NSMutableArray *insertIndexPaths = [NSMutableArray arrayWithCapacity:10];     
13.     for (int ind = 0; ind < [data count]; ind++) {     
14.         NSIndexPath    *newPath =  [NSIndexPath indexPathForRow:[listData indexOfObject:[data objectAtIndex:ind]] inSection:0];     
15.         [insertIndexPaths addObject:newPath];     
16.     }     
17.     //重新调用UITableView的方法, 来生成行.  
18.     [self.tbView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationFade];     
19.  }

这些函数看着挺多的, 其实仔细看看也并不复杂, 当你实现了UITableView的接口后, 除了 loadMore, appendTableWitdh 以及定义的分页函数GetRecord, 其余的都是在实现UITableView的接口中定义的方法.