ios开发——用UITableView展示多行多列图片
来源:互联网 发布:即时聊天软件 行业 编辑:程序博客网 时间:2024/04/29 16:09
有时我们可能需要用UITableView通过自定义Cell的方法来展示多行多列的图片,实现类似与UICollectionView的效果。例如电子书等应用。这里我们来实现这个功能。
首先可以自定义一个UIView来代表Cell内的每一个Item,然后以每行三列为例,将其布局到每个cell上。
对这个自定义cell,暴露出一个NSArray属性groupedItem(已分好组的Item)表示有三个Item的数组,这样在TableView中只要cell.groupedItem = ……,在cell中将这三个Item拿出来,分别为View提供数据,让View展示数据即可。
因此关键就是将数据模型(Model)分成2维数组,每个子数组有三个元素。
当从网络上或本地获取所有数据保存到字典中后,可以对这个数组每三个元素加入到一个新数组,然后新数组加入到最终的二维数组。即
<span style="font-size:14px;">NSMutableArray *tempArray = nil; for (int i = 0; i < self.allBooks.count; i++) { if (i % 3 == 0) { tempArray = [NSMutableArray arrayWithCapacity:3]; [self.bookGroup addObject:tempArray]; } [tempArray addObject:[self.allBooks objectAtIndex:i]]; }</span>
allBooks代表保存所有数据的数组,bookGroup表示最终的二维数组。
分好组以后就可以在tableview数据源协议方法中为cell提供数据
<span style="font-size:14px;">- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *cellId = @"CYZBookShelfViewCell"; CYZBookCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { cell = [[CYZBookCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } cell.booksGroup = [self.bookGroup2D objectAtIndex:indexPath.row]; return cell;}</span>
在Cell中定义一个数组来接收该行显示的三个Model
<span style="font-size:14px;">@interface CYZBookCell : UITableViewCell/**本cell要展示的三本书*/@property (strong, nonatomic) NSArray *booksGroup;@end</span>
然后再initView时建立三个子视图并加入到cell.contentView中,分别为这三个view赋tag值以便在layoutSubview中取得。接着在layoutSubview中设置这三个view的位置、数据等信息。
<span style="font-size:14px;"> for (int i = 0; i < self.booksGroup.count; i++) { CYZBookItemView *item = (CYZBookItemView *)[self.contentView viewWithTag:100 + i]; item.frame = CGRectMake(kHorizontalEdge + (kHorizontalEdge + 80) * i, kVerticalEdge, 80, 150); item.hidden = NO; //有数据的item不隐藏 item.bookModel = [self.booksGroup objectAtIndex:i]; [self addSubview:item]; //如果不添加以下方法,那么在cell复用时将不会调用子视图的layoutSubview方法,这样数据就无法更新了。 [item setNeedsLayout]; [item layoutIfNeeded]; }</span>
为什么要再layoutSubview中调用item的setNeedsLayout方法呢?这是因为Cell的复用问题,当cell复用时并不会调用item的layoutSubview方法,因此上拉tableview时展示出来的数据全是与之前重复的。所以我们需要手动让item重新布置子视图。
另一个由cell复用机制引发的问题:依旧是数据重复
我们的数据一般是从网上来的,故数据的数量并不确定,很有可能不是恰好为3的倍数。例如有40个,这是你会发现,本来最后一样应该只有一个数据,却出现了三个,并且后两个是重复的。这就是cell复用引发的另一个问题,为了解决这一问题,我们应该让无数据的item隐藏。怎么判断item有没有数据呢?在上述for循环中,self.booksGroup中保存了有数据的item,因此能进入for循环的即为有数据的。在这里让item显示。
因此,我们可以复写booksGroup的setter,让所有的数据默认隐藏。
<span style="font-size:14px;">- (void)setBooksGroup:(NSArray *)booksGroup{ _booksGroup = booksGroup; for (int i = 0; i < booksGroup.count; i++) { CYZBookItemView *item = (CYZBookItemView *)[self.contentView viewWithTag:100 + i]; //由于cell的复用问题,当数据并不为3的整数倍时第三个item会填充之前的数据,造成数据重复 //为了修正这个问题,没有数据的item应该隐藏,故这里将所有的item隐藏,在layoutSubview方法中有数据的item不隐藏 item.hidden = YES; }}</span>
总结一下:
1、我们需要一个自定义视图Item表示在每行cell中的每一列,item可以包含图片、lable……自定义视图,主要功能为展示数据,只要将model对象给他,他就能展示model中的数据。
2、同时还需要一个自定义cell来盛下item,每个cell可以容纳多列,只要传给他一组数组,里面包含这一行的每一列的model对象即可,然后cell将每一个model分别给每一个item。
3、在tableView或其他控制器中将所有数据分组,分成二维数组,每一维都是每一行cell中的所有model,然后在tableview数据源协议中将二维数组的每一个元素(一维数组)分别给每一行让其显示该行的数据。
4、注意在这一过程中由于cell复用引发的一系列数据重复的问题,解决方法:1)手动调用item的setNeedsLayout方法让item刷新。2)让没数据的item隐藏,有数据的item显示。
- ios开发——用UITableView展示多行多列图片
- ios开发——用UITableView展示多行多列图片
- IOS开发UI展示之UITableView ──分页加载
- IOS开发UI展示之UITableView ──分页加载
- IOS开发UI展示之UITableView ──分页加载
- IOS开发UI展示之UITableView ──分页加载
- iOS开发学习笔记——UITableview
- UITableView——实现汽车分组展示
- iOS 开发 图片缩略图的生成,展示图片中间一部分
- iOS 开发 图片缩略图的生成,展示图片中间一部分
- iOS 开发 图片缩略图的生成,展示图片中间一部分
- iOS——UITableView
- iOS——UITableView
- iOS开发之UITableView点击头部控件图片旋转问题
- iOS开发UITableView中ImageView图片的延迟加载思路
- IOS开发UI展示之UITableView ──分页加载更多
- IOS开发UI展示之UITableView ──分页加载更多
- IOS开发UI展示之UITableView ──分页加载更多
- 排序8:选择排序(堆排序)
- 好消息!国产编程语言RPP 1.86 开源发布!
- swift用全局常量代替宏
- Android任务、进程、线程详解
- HTTP 头 Connection=close 作用
- ios开发——用UITableView展示多行多列图片
- [LeetCode] Palindrome Partitioning I
- 协变与逆变
- [LeetCode] Palindrome Partitioning II
- 《浪潮之巅》11 硅谷的另一面
- Java中的序列化
- PHP发送邮件带附件
- 引用和指针
- SQL Server 2012 发送邮件