IOS学习之tableView扩展

本文详细介绍了在iOS应用中实现代理模式下的加载更多功能,包括代码实现、关键部分解释及最终效果展示。通过实例代码,读者可以了解如何在UITableView中动态加载数据,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一篇(IOS学习之tableview示例)基础上,实现常见的“加载更多功能”,即最下方的cell点击可以触发加载更多的数据源,并增加cell显示.

 

本篇只重点说明新增的地方,和上一篇重复的知识点,不再累述。先上个最终的效果图:



还是直接上代码, 首先头文件里,

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @interfaceViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>  
  2. {  
  3.     UITableView * m_tableView;  
  4.     NSMutableArray*arrayList;  
  5. }  
  6.    
  7.    
  8. @property (nonatomic ,retain)  UITableView * m_tableView;  
  9.    
  10. -(void)appendCellWith:(NSMutableArray *)data;  
  11. -(void) doAllTest;  


不多说,直接看.m文件

 

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  
  2. {  
  3.      
  4.     //设置头标题  
  5.     UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(00, CGRectGetWidth(self.view.frame), 40)];  
  6.    label.text = @"加载更多测试";  
  7.    tableView.tableHeaderView = label;  
  8.      
  9.     m_tableView = tableView;//注意这里  
  10.     return 1;  
  11. }  

这个函数里有个关键就是把tableview的变量实例取出来,因为后面有成员函数要显示的调用。

 

 

下面这个不需要多说,

 

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell*)tableView:(UITableView *)tableView  
  2.          cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  3. {  
  4.     static NSString *CellIdentifier = @"Cell";  
  5.      
  6.     UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  7.     if (cell == nil)  
  8.     {  
  9.         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  10.     }  
  11.      
  12.     NSLog(@"%d",[arrayList count]);  
  13.      
  14.     if ([indexPath row] <= [arrayList count] - 1)  
  15.     {  
  16.         cell.textLabel.textColor  =[UIColor orangeColor];  
  17.         cell.textLabel.text = [arrayList objectAtIndex:indexPath.row];  
  18.     }  
  19.     else  
  20.     {  
  21.         cell.textLabel.textColor  =[UIColor blueColor];  
  22.         cell.textLabel.text = @"点击加载更多";  
  23.     }  
  24.     returncell;  
  25. }  

 

继续上代码:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     if (indexPath.row == [arrayList count])  
  4.     {  
  5.          
  6.          
  7.         [self doAllTest];  
  8.    
  9.         NSIndexPath *index = [NSIndexPath indexPathForRow:indexPath.row+3inSection:0];  
  10.         NSLog(@"new indexPath.row:%u", index.row);  
  11.           
  12.          [tableView deselectRowAtIndexPath:indexanimated:YES];  
  13.        
  14.        return;  
  15.     }  
  16. }  

deselectRowAtIndexPath 这个调用是取消选定状态,这一句如果不加,加载完新的cell后,最后一个cell依然是选定的状态.

 

最后两个方法实现,

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)appendCellWith:(NSMutableArray *)data  
  2. {  
  3.     NSLog(@"appendTableWith");  
  4.      
  5.     for (int i = 0 ; i < [data count] ; i++)  
  6.     {  
  7.         [arrayList addObject:[data objectAtIndex:i]];  
  8.     }  
  9.     NSMutableArray*insertIndexPaths = [NSMutableArray arrayWithCapacity:10];  
  10.      
  11.     for (int j = 0; j < [data count]; j++)  
  12.     {  
  13.         NSIndexPath *newPath  =[NSIndexPath indexPathForRow:[arrayList indexOfObject:[data objectAtIndex:j]] inSection:0];  
  14.         [insertIndexPaths addObject:newPath];  
  15.     }  
  16.     [m_tableView insertRowsAtIndexPaths:insertIndexPathswithRowAnimation:UITableViewRowAnimationFade];  
  17. }  
  18.    
  19.    
  20. -(void) doAllTest  
  21. {  
  22.     NSLog(@"doAllTest");  
  23.     NSMutableArray *moreArray = nil;  
  24.    moreArray = [NSMutableArray arrayWithObjects:@"苹果",@"橘子",@"香蕉", nil nil];  
  25.     [self appendCellWith:moreArray];  
  26. }  


另外再说一种方法,这种方法是网上看到的,比我的实现复杂一些,用到了多线程,但是从软件设计的角度看,是很好的,因为这种”加载更多”功能,是应该在后台开一个线程去获取新的数据源比较好,然后再用新的数据源更新主线程的UI显示。看代码自会明白.

 

先增加一个函数声明和实现,

 

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)loadMore;  
  2.    
  3. -(void)loadMore  
  4. {  
  5.     NSLog(@"loadMore");  
  6.     NSMutableArray *moreArray = nil;  
  7.     moreArray = [NSMutableArray arrayWithObjects:@"苹果",@"橘子",@"香蕉", nil nil];  
  8.      
  9.     if (moreArray != nil )  
  10.     {  
  11.         [self performSelectorOnMainThread:@selector(appendCellWith:)withObject:moreArray waitUntilDone:YES];  
  12.     }  
  13.      
  14. }  


在主线程之外的线程更新主线程所显示的界面元素,不能直接调用主线程的类的更新界面的方法,否则界面看不到任何结果,要调用一个方法:

performSelectorOnMainThread.

waitUntilDone指定当前线程是否要被阻塞?另外注意一下selector里面这个冒号,加冒号表示这个方法存在参数,没有参数就不用加冒号.

 

然后就可以直接调用这个子线程了:

 

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     if (indexPath.row == [arrayList count])  
  4.     {  
  5.          
  6.         [self performSelectorInBackground:@selector(loadMore)withObject:nil];  
  7.          
  8.          
  9.         NSLog(@"indexPath.row:%u",indexPath.row);  
  10.          
  11.         [tableView deselectRowAtIndexPath:indexPathanimated:YES];  
  12.         return;  
  13.     }  
  14. }  


在服务器端获取完数据通过后台使用多线程方式自动更新UI, 通常的方法是

使用NSObject类的方法performSelectorInBackground:withObject:来创建一个线程。调用之后,会立即创建一个线程并执行selector方法

 

注意到这里取消选择状态时,index并没有加3,是因为这个时候索引还没有变,只是开启了一个子线程去后台处理,要好好体会与上面的差异性。或者可以用同步和异步来理解是否容易一些呢?

 

源码下载:

http://download.youkuaiyun.com/detail/pony_maggie/7163881

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值