• UITableView实现加载更多数据


    类似于微博、博客这样的应用,通常都需要数据分页。而数据分页常用的做法是在UITableView控件上追加新的数据。从而有效提高用户体验。接下来将介绍其实现过程。

    一、实现思路

    基本上就是数据源里先只放10条, 点击最后一个cell时, 添加更多的数据到数据源中。

    1)取得数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    - (void)viewDidLoad
    {
        [super viewDidLoad]; 
        [self _infoNavTabBar];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        num=15;
        //表格数据
        [self loadData];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
    }

    loadData方法用于拉取API数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //下载API数据
    -(void) loadData{
        _ASIHTTPRequest=[[ASIHTTPRequest alloc] initWithURL:requestURL];
        _ASIHTTPRequest.delegate=self;
        [_ASIHTTPRequest startAsynchronous]; 
        [_ASIHTTPRequest release];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        //声明表格
        _tableView=[[[UITableView alloc] init] autorelease];
        _tableView.frame=self.view.bounds;
        _tableView.delegate=self;
        _tableView.dataSource=self;
        [self.view addSubview:_tableView];
        _tableView.frame=CGRectMake(0, 0, [self appWidth], [self appHeight]-90);
    }
    //数据异步下载完成
    - (void)requestFinished:(ASIHTTPRequest *)request{
        NSString *_data=[request responseString];
        NSMutableDictionary *dir=[_data JSONValue];
        dic_=[[NSMutableDictionary alloc] initWithDictionary:[dir objectForKey:@"data"]];
        [_tableView reloadData];
    }


    2)追加“加载更多”单元格记录

    1
    2
    3
    4
    5
    6
    7
    8
    //表格单元行数
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        NSArray *rotStr=[dic_ objectForKey:@"rows"];
        count = [rotStr count];
        NSLog(@"总记录%d",count);
        return  count+1;
    }

    如上述代码所示,记录数量+1的目的就是为了在原有的UITableViewCell上追加一个“加载更多”的Cell。由于API返回的数据是一个层的Dictionary,所以需要使用[dic_objectForKey:@"rows"]代码提取所需要显示的数据行数。


    3)为UITableView追加单元格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //表格单元格数据
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        NSString *identifier=@"mycell";
        UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier];
        NSInteger row=(indexPath.row)-1;
        if (row<=0) row=0;
        UILabel *label = nil;
        if (cell==nil) {
            cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];     
        [cell autorelease];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        }
        if([indexPath row] == ([rotStr count])) {
            //创建loadMoreCell
            UITableViewCell *moreCell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"mores"] autorelease];
            UILabel *moreDataLabel=[[UILabel alloc] init];
            moreDataLabel.text=@"查看更多";
            [moreDataLabel setFont:[UIFont systemFontOfSize:14.0f]];
            [moreDataLabel setTextAlignment:NSTextAlignmentCenter];
            moreDataLabel.frame=CGRectMake(0, 10, [self screenWidth], 20);
            [moreDataLabel setBackgroundColor:[UIColor clearColor]];
            [moreCell.contentView addSubview:moreDataLabel];
            NSLog(@"更多...");
            return moreCell;
        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    }

    如上述代码所示,由于在返回表格数据记录时+1,所以在遍历表格数据时需要做相应的处理(即-1),否则将会遍历越界。同时可判断当前的遍历索引是否为数据的总记录,如果是则执行添加“加载更多”的UITableViewCell。当然,一般“加载更多”那个Cell高度是不一样的,所以设置单元格高度时同样也需要做判断处理。如以下代码所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //单元格高度
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        if (indexPath.row==count) {
            return 40;
        }else{
            UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
            return cell.frame.size.height;
        }
    }


    4)处理“加载更多”单元格事件

    处理UITableViewCell选择触发事件,是通过didSelectRowAtIndexPath委托方法实现的。同样我们需要在该方法中判读用户所选择的单元格是否为“加载更多”单元格。通过选择索引号即可实现,代码如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //单元格事件
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
                                                                                                                                                                                                                                                                                                                                                                                                                                              
        if (indexPath.row == count) {
        //”加载更多“单元格事件
            [self performSelectorInBackground:@selector(loadMore) withObject:nil];
            //[loadMoreCell setHighlighted:NO];
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
            return;
        }
        //其他单元格事件
                                                                                                                                                                                                                                                                                                                                                                                                                                              
    }


    5)追加数据

    用户点击”加载更多“单元格后,将触发loadMore方法,在该方法中实现分页数据的拉取。为了提高效率,所以这里使用了performSelectorInBackground方法创建后台了线程。loadMore方法代码如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    //1、点击加载更多数据
    -(void)loadMore
    {
        page++;
        if (page<=3) {
            page=3;
        }
        //在子线各中处理同步请求
        [self performSelectorOnMainThread:@selector(SynchronousData:) withObject:nil waitUntilDone:NO];
                                                                                                                                                                                                                                                                 
    }
    //2、请求数据
    -(void) SynchronousData:(NSMutableDictionary *)data
    {
        //加载你的数据
        NSLog(@"n请求的URL:%@n",url);
        ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL :url];
                                                                                                                                                                                                                                                                 
        // 开始同步请求
        [request startSynchronous];
        NSError *error = [request error ];
        assert (!error);
        NSString *requestStr=[request responseString];
                                                                                                                                                                                                                                                                 
        NSMutableDictionary *dir=[requestStr JSONValue];
        NSMutableDictionary *str=[dir objectForKey:@"data"];
        NSMutableArray *rotStr=[str objectForKey:@"rows"];
        [self performSelectorOnMainThread:@selector(appendTableWith:) withObject:rotStr waitUntilDone:NO]; 
                                                                                                                                                                                                                                                                 
    }
    //3、根据请求的数据动态添加单元
    -(void) appendTableWith:(NSMutableArray *)data
    {
        for (int i=0;i<[data count];i++) {
            [[dic_ objectForKey:@"rows"] addObject:[data objectAtIndex:i]];
            //[data_ addObject:[data objectAtIndex:i]];
        }
        NSMutableArray *insertIndexPaths = [NSMutableArray arrayWithCapacity:10];
        for (int ind = 0; ind < [data count]; ind++) {
            NSIndexPath    *newPath =  [NSIndexPath indexPathForRow:[[dic_ objectForKey:@"rows"] indexOfObject:[data objectAtIndex:ind]] inSection:0];
            [insertIndexPaths addObject:newPath];
        }
        [self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationFade];
                                                                                                                                                                                                                                                                 
    }

    如上述代码所示,共分为3个步骤。首先由loadMore方法初始化请求变量,例如修改请求链接的分页码等;然后在SynchronousData方法中同步获取API接口中的数据;最后在appendTableWith方法中完成UITableViewCell单元格的动态添加。



  • 相关阅读:
    oracle按用户导出导入表
    一次简单的springboot+dubbo+flume+kafka+storm+redis系统
    数据库索引学习
    springboot-quartz 实现动态添加,修改,删除,暂停,恢复等功能
    springboot + rabbitmq 整合示例
    springboot-quartz普通任务与可传参任务
    eclipse里maven项目An error occurred while filtering resources解决办法
    job调度时间格式
    多线程发送短信和微信公众号推送消息
    SerializeUtil 序列化,反序列化工具类
  • 原文地址:https://www.cnblogs.com/xukunhenwuliao/p/3576235.html
Copyright © 2020-2023  润新知