淘宝的搜索出来的商品列表可以切换样式,下面是在一个pdf的demo里面模仿了淘宝的这个功能,点一下左上角的change style,界面由三列变成单列,你可以使用一个tableView+collectionView实现,当然,这是比较费力的办法,我们这次,只用collectionView来实现这个效果,姿势用的好,没有xxx推不倒

众所周知,collectionView可以自定义布局来实现圆形布局,瀑布流布局,对于这个效果,我们直接使用官方提供的uicollectionviewflowlayout,uicollectionviewflowlayout如同其名,在每一行,一个接一个排列,当所剩的位置不足以容下一个新的cell的时候,另起一行,所以,对于一列的情况,我们可以将cell的宽度设置为等于collectionView的宽度,这样每行只有一个cell,效果就和tableView一样;对于多列的情况,只要控制好cell的宽度,也可以轻松实现,关键在cell的size控制,cell的size又由layout的size所决定,所以核心操作都在
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
Just do it
新建一个项目,在SB里面放入一个collectionView,再拖入一个collectionViewCell,修改样式如下:
选中collectionView,在右边的属性栏将items改为2:

这时,collectionView中多了一个cell,我们将另一个的样式修改,最终在SB中的效果如下:

nice,我们已经完成了ui的部份,接下来,我们需要新建OneColumCell和MulColumCell对应我们在SB中的两个cell,这里只贴出.m的代码:
OneColumCell.m
#import "OneColumCell.h"
#import "ProductInfoModel.h"
@interface OneColumCell()
@property (weak, nonatomic) IBOutlet UIImageView *mImageView;
@property (weak, nonatomic) IBOutlet UILabel *mTitleLabel;
@property (weak, nonatomic) IBOutlet UILabel *mDescLabel;
@property (nonatomic, strong) ProductInfoModel *model;
@end
@implementation OneColumCell
- (void)setProductInfoModel:(ProductInfoModel *)model{
_model = model;
_mTitleLabel.text = model.title;
_mDescLabel.text = model.desc;
if (model.image) {
_mImageView.image = model.image;
}
}
@end
MulColumCell.m
#import "MulColumCell.h"
#import "ProductInfoModel.h"
@interface MulColumCell()
@property (weak, nonatomic) IBOutlet UIImageView *mImageView;
@property (weak, nonatomic) IBOutlet UILabel *mTitleLabel;
@property (nonatomic, strong) ProductInfoModel *model;
@end
@implementation MulColumCell
- (void)setProductInfoModel:(ProductInfoModel *)model{
_model = model;
_mTitleLabel.text = model.title;
if (model.image) {
_mImageView.image = model.image;
}
}
@end
好了,是时候回到我们的ViewController中,将一切关联起来,揭开神秘的面纱
我们需要一个状态来区分当前是单列或者多列
@property (nonatomic, assign) BOOL isSingleLine;
ViewController实现UICollectionViewDelegateFlowLayout和UICollectionViewDataSource协议
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ProductInfoModel *model = self.dataArray[indexPath.row];
if (self.isSingleLine)//1
{
OneColumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([OneColumCell class]) forIndexPath:indexPath];
[cell setProductInfoModel:model];
return cell;
}
else
{
MulColumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([MulColumCell class]) forIndexPath:indexPath];
[cell setProductInfoModel:model];
return cell;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
if (self.isSingleLine) {
return CGSizeMake([self screenSize].width, 139);//2
}
return CGSizeMake([self screenSize].width / kColumn , 143);//3
}
1.根据self.isSingleLine,返回不同的cell
2.此处是单列模式,将width设置为当前屏幕的宽度
3.此处是多列模式,根据定义的列数kColumn,计算出对应的宽度,在这里,我们的高度写成一个固定值是偷懒了,实际开发中应该是根据不同的屏幕去生成不同的高度,以便更好的适配
风风火火写了这么多,是时候让新娘子出来见见人了,run~

看起来效果不错,等等,等等,我们刚才的kColumn明明是3,这里为什么还是两列
static const NSInteger kColumn = 3;
我们再仔细观察一下,我们发现cell与cell之间有个大概10个点的白色间距,这里我们将cell 的背景色设置为黄色可以更好的看出这些间距,既然上下之间有了间距,所以有没有可能左右也有呢,因为我们的屏幕刚好要放下三个cell ,没有预留边距的位置,所以如果多处了间距的话,就会导致这情况,我们查看SB的属性

我们将图所圈的全部改为0,再次run~

去掉了默认的边距之后,已经达到了我们想要的效果,本文的Demo点此下载