再来说一说UITableView的分页

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

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

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

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

select * from table where 列名 = 条件 limit 页数 * 每页显示记录数,每页显示记录数
+(NSMutableArray *)GetRecord:(NSInteger)p
{   //代码中,除了SQLITE的SELECT操作之外,和分页有关系的就是参数p和下面分页的SQL语法拼接形式了.
  NSString *query = [NSString stringWithFormat:@"select * from table order by ID limit %d,10",(p-1) * 10];
  char *select =(char *)[query UTF8String];
  NSMutableArray *array = [[NSMutableArray alloc] init];
  sqlite3 *database;
  if(sqlite3_open([DbObject GetDatabasePath],&database) == SQLITE_OK)
  {
    sqlite3_stmt *statement;
    if(sqlite3_prepare_v2(database,select,-1,&statement,nil)== SQLITE_OK)
    {
      while (sqlite3_step(statement) == SQLITE_ROW)
      {
                 //根据字段的类似,使用sqlite3_column_init,sqlite3_column_blob,sqlite3_column_text等将数据从记录行中取出来. 此处代码略
                //然后将出来的值,以键值对应的形式赋值给NSDictionary数组.
        NSDictionary *rowRecord = [[NSDictionary alloc] initWithObjectsAndKeys:nsID,@"ID",data,@"Image",nsMessage,@"Message",nsVideoURL,@"VideoURL",nsAudioURL,@"AudioURL",nsToLine,@"ToLine",nsSendDate,@"SendDate",nil];
	    //将NSDictionary添加到NSMuableArray数组中.
        [array addObject:rowRecord];
    }
    sqlite3_finalize(statement);
  }
  sqlite3_close(database);
  }
  return array;
}
当然了这个函数还要在你的h文件中声明,然后才可以在m文件中implement,否则当你使用 [类名 函数名:参数] 访问时会找不到方法的.


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

NSInteger currentPage;
@property(strong,nonatomic) IBOutlet NSMutableArray *listData;
@property(strong,nonatomic) IBOutlet UITableView *tbView;

3. 在系统初始化时,将变量的值设置为1,然后对UITableView对象使用到的数据源进行赋值.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    currentPage = 1;
    listData = [DbMyClass GetRecord:currentPage];
}

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

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger row = [listData count];
    return row +1;
}

5. 然后我们在 cellForRowAtIndexPath 中正常处理我们的单元格信息,比如说我们使用了自定义单元格,我们就要在这里加载... 这是最重要的一点是,需要判断[indexPath row] =和[ listData count]的值是否相同,如果相同,那么就需要加载我们的分页按钮了.

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellTableIdentifier = @"CusCellFutureMessage";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
    if(cell == nil)
    {
        if([indexPath row] == [listData count])
        {
            //新建一个单元格,并且将其样式调整成我们需要的样子.
            cell=[[UITableViewCell alloc] initWithFrame:CGRectZero 
                                         reuseIdentifier:@"LoadMoreIdentifier"]; 
            cell.font = [UIFont boldSystemFontOfSize:13];  
            cell.textLabel.text = @"读取更多...";
        }
        else
        {
               //其它单元格的初始化事件. 自定义单元格的读取,或者是单元格的设置等.
        }
    }
    return cell;
}

6. 然后就是注册UITableView被点击之后,要触发的事件了. 事件需要在 didSelectRowAtIndexPath 中定义

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([indexPath row] == [listData count])
    {
        UITableViewCell *loadMoreCell=[tableView cellForRowAtIndexPath:indexPath];   
        loadMoreCell.textLabel.text=@"正在读取更信息 …";   
        [self performSelectorInBackground:@selector(loadMore) withObject:nil];   
        [tableView deselectRowAtIndexPath:indexPath animated:YES];   
        return;  
    }
    else
    {
         //其它单元格的事件  
    }
}

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

-(void)loadMore   
{   //当你按下这个按钮的时候,意味着你需要看下一页了,因此当前页码加1
    currentPage ++;
    NSMutableArray *more = [DbMyClass GetRecord:currentPage]; //通过调用GetRecord方法,将数据取出. 
    [self performSelectorOnMainThread:@selector(appendTableWith:) withObject:more waitUntilDone:NO];   
}   
-(void) appendTableWith:(NSMutableArray *)data   
{   //将loadMore中的NSMutableArray添加到原来的数据源listData中.
    for (int i=0;i<[data count];i++) {   
        [listData addObject:[data objectAtIndex:i]];   
    }   
    NSMutableArray *insertIndexPaths = [NSMutableArray arrayWithCapacity:10];   
    for (int ind = 0; ind < [data count]; ind++) {   
        NSIndexPath    *newPath =  [NSIndexPath indexPathForRow:[listData indexOfObject:[data objectAtIndex:ind]] inSection:0];   
        [insertIndexPaths addObject:newPath];   
    }   
    //重新调用UITableView的方法,来生成行.
    [self.tbView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationFade];   
}  
这些函数看着挺多的,其实仔细看看也并不复杂,当你实现了UITableView的接口后,除了 loadMore,appendTableWitdh 以及定义的分页函数GetRecord,其余的都是在实现UITableView的接口中定义的方法.

相关文章

SQLite架构简单,又有Json计算能力,有时会承担Json文件/RES...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器...
安卓开发,利用SQLite实现登陆注册功能