UICollectionView详解五:瀑布流

前面四个章节,我已经详细的讲解了UICollectionView的使用,这一节,我用一个非常实用的例子“瀑布流”来进一步说明UICollectionView的强大作用。

先分析一下瀑布流的特点:

1. 所有item的宽度是一致的。

2. 所有item应该是等比例缩放的。

3. 所有item的高度应该是通过实际宽度与缩放比例计算而得出的。

4. 要保证每一列的底部的y值均匀分布,,不能偏差很大。

5. 瀑布流不是常规的流式布局,所以应该使用UICollectionViewLayout,对UICollectionViewLayout不明白的,请参考我前面写的章节,请点击这里。

下面是运行效果图:

1. 竖屏

2. 横屏

好的,下面,我们来一步步的实现这个效果。

1.准备数据源(我使用的是plist文件,实际开发中游可能是json数据,不过是差不多的):

对数据源的说明:

注意:需要服务器端提供图片的宽度和高度的信息(h,w两个值)。如果我们不把宽度和高度信息放在数据源中,那么当图片信息获取后,我们自己还要在前端自己计算宽度和高度。在网络不好的情况下,有的图片也许长时间加载不到,那么我们就不知道怎么去布局了。如果提供了图片的宽度和高度信息,就算图片没有加载到,但是宽度和高度信息是可以获取到的,这个时候,我们可以放置占位图片,等图片加载完毕后,再替换掉占位图片。

2. 建立对应的模型

@interface LFShop : NSObject/*图片的宽度*/@property (nonatomic,assign) CGFloat w;/*图片的高度*/@property (nonatomic,assign) CGFloat h;/*图片的url*/@property (nonatomic,copy) NSString *img;/*图片的价格信息*/@property (nonatomic,copy) NSString *price;@end3. 自定义UICollectionViewCell,用来显示最终的图片信息

@class LFShop;@interface LFWaterFlowCell : UICollectionViewCell@property (weak, nonatomic) IBOutlet UIImageView *imageView;@property (weak, nonatomic) IBOutlet UIButton *priceBtn;@property (nonatomic,strong) LFShop *shop;@end@implementation LFWaterFlowCell-(void)setShop:(LFShop *)shop {_shop = shop;[self.imageView sd_setImageWithURL:[NSURL URLWithString:shop.img] placeholderImage:[UIImage imageNamed:@"placeholder.jpg"] options:SDWebImageRetryFailed];[self.priceBtn setTitle:shop.price forState:UIControlStateNormal];}@endxib结构图

4. 在控制器ViewController.m中初始化UICollectionView,及设置数据源方法

@interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,LFWaterFlowLayoutDelegate>@property (nonatomic,strong) NSMutableArray *shops;@property (nonatomic,weak) LFWaterFlowLayout *layout;@property (nonatomic,weak) UICollectionView *collectionView;@property (nonatomic,assign,getter=isLoadRotate) BOOL loadRotate;@endstatic NSString *const identifer = @"LFWaterFlowCell";@implementation ViewController#pragma mark – Lazy Load-(NSMutableArray *)shops {if (!_shops) {NSArray *defaultArray = [LFShop objectArrayWithFilename:@"2.plist"];_shops = [NSMutableArray array];[_shops addObjectsFromArray:defaultArray];}return _shops;}#pragma mark – init- (void)viewDidLoad {[super viewDidLoad];[self collectionViewInit];}- (void)collectionViewInit {LFWaterFlowLayout *layout = [[LFWaterFlowLayout alloc] init];layout.delegate = self;self.layout = layout;//layout.insets = UIEdgeInsetsMake(20, 20, 20, 20);//layout.count = 4;UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];collectionView.dataSource = self;collectionView.delegate = self;collectionView.backgroundColor = [UIColor darkGrayColor];[self.view addSubview:collectionView];// autolayout全屏幕显示[collectionView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];[collectionView registerNib:[UINib nibWithNibName:@"LFWaterFlowCell" bundle:nil] forCellWithReuseIdentifier:identifer];self.collectionView = collectionView;}#pragma mark – UICollectionView // Datasource- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return self.shops.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {LFWaterFlowCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifer forIndexPath:indexPath];cell.shop = self.shops[indexPath.item];return cell;}- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {LFShop *shop = self.shops[indexPath.item];NSLog(@"Item Price:%@",shop.price);}@end代码中,大家可以看到,我定义了一个LFWaterFlowLayout,它就是用来对UICollectionView进行布局的。

5. 在看具体代码之前,我们先看看瀑布流的具体结构示意图。

世界会向那些有目标和远见的人让路(冯两努——香港着名推销商

UICollectionView详解五:瀑布流

相关文章:

你感兴趣的文章:

标签云: