zoukankan      html  css  js  c++  java
  • 【代码笔记】自定义布局实现瀑布流

    利用collectionView实现瀑布流的效果,

    文件目录如下

    动画效果图如下:

     1 //ViewController文件
     2 
     3 #import "ViewController.h"
     4 #import "LYWaterFlowLayout.h"
     5 #import "LYWaterCell.h"
     6 #import "LYShopModel.h"
     7 
     8 @interface ViewController ()<UICollectionViewDataSource>
     9 @property(nonatomic,strong)NSArray *shops;
    10 
    11 
    12 @end
    13 
    14 @implementation ViewController
    15  static NSString *ID = @"water";
    16 
    17 - (NSArray *)shops{
    18     
    19     if (_shops == nil) {
    20 //        1.读取文件
    21         NSString *path =  [[NSBundle mainBundle ]pathForResource:@"1.plist" ofType:nil];
    22        NSArray *dictArray =  [NSArray arrayWithContentsOfFile:path];
    23 //        2.字典转模型
    24         NSMutableArray *tempArray = [NSMutableArray array];
    25         for (NSDictionary *dict in dictArray) {
    26             LYShopModel *shop = [LYShopModel shopWithDict:dict];
    27             [tempArray addObject:shop];
    28             
    29         }
    30         _shops = tempArray;
    31         
    32         
    33         
    34     }
    35     return _shops;
    36 }
    37 
    38 - (void)viewDidLoad {
    39     [super viewDidLoad];
    40     // Do any additional setup after loading the view, typically from a nib.
    41 //    0.自定义布局
    42     LYWaterFlowLayout *waterFlowLayout = [[LYWaterFlowLayout alloc]init];
    43 //    0.1.传递外界数组到内部
    44     waterFlowLayout.shops = self.shops;
    45     
    46 //    1.创建collectionView
    47     UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) collectionViewLayout:waterFlowLayout];
    48 //    2.设置数据源
    49     collectionView.dataSource = self;
    50 ////    3.设置代理
    51 //    collectionView.delegate = self;
    52     
    53 
    54 //    3.添加
    55     [self.view addSubview:collectionView];
    56 //    4.注册cell
    57     [collectionView registerNib:[UINib nibWithNibName:@"LYWaterCell" bundle:nil] forCellWithReuseIdentifier:ID];
    58     
    59     
    60 }
    61 
    62 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    63     
    64     return  1;
    65     
    66 }
    67 
    68 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    69     
    70     return self.shops.count;
    71 }
    72 
    73 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    74     
    75     
    76 //    1.创建cell
    77    
    78     LYWaterCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    79 //    2.赋值
    80 //
    81 //    cell.backgroundColor = [UIColor redColor];
    82 //    2.1获取模型
    83     LYShopModel *shop = self.shops[indexPath.item];
    84     cell.shop = shop;
    85     
    86     cell.indexPath=indexPath;
    87 //   3.返回cell
    88     return cell;
    89     
    90     
    91 }
    92 
    93 @end
     1 //LYWaterCell文件
     2 #import <UIKit/UIKit.h>
     3 @class LYShopModel;
     4 
     5 @interface LYWaterCell : UICollectionViewCell
     6 @property(nonatomic,strong)LYShopModel *shop;
     7 
     8 @property(nonatomic,strong)NSIndexPath *indexPath;
     9 
    10 @end
    11 
    12 
    13 
    14 
    15 
    16 #import "LYWaterCell.h"
    17 #import "LYShopModel.h"
    18 
    19 @interface LYWaterCell()
    20 
    21 @property (weak, nonatomic) IBOutlet UIImageView *iconView;
    22 @property (weak, nonatomic) IBOutlet UILabel *priceLabel;
    23 
    24 @end
    25 @implementation LYWaterCell
    26 - (void)setShop:(LYShopModel *)shop{
    27     
    28     _shop = shop;
    29   
    30     self.iconView.image = [UIImage imageNamed:shop.icon];
    31     //self.priceLabel.text = shop.price;
    32     
    33 }
    34 -(void)setIndexPath:(NSIndexPath *)indexPath{
    35     
    36     _indexPath = indexPath;
    37     self.priceLabel.text = self.shop.price;
    38     
    39 }
    40 
    41 @end
      1 //LYWaterFlowLayout文件
      2 #import <UIKit/UIKit.h>
      3 
      4 @interface LYWaterFlowLayout : UICollectionViewFlowLayout
      5 
      6 
      7 
      8 @property(nonatomic,strong)NSArray *shops;
      9 
     10 
     11 @end
     12 
     13 
     14 
     15 
     16 
     17 int const column = 3;
     18 #import "LYWaterFlowLayout.h"
     19 #import "LYShopModel.h"
     20 
     21 @interface LYWaterFlowLayout()
     22 
     23 @property(nonatomic,strong)NSMutableArray *maxYs;
     24 @end
     25 
     26 @implementation LYWaterFlowLayout
     27 - (NSMutableArray *)maxYs{
     28     
     29     if (_maxYs == nil) {
     30         _maxYs = [NSMutableArray array];
     31         NSLog(@"%@",_maxYs);
     32         
     33     }
     34     
     35     return _maxYs;
     36 }
     37 
     38 /**
     39  *  用来设置每一个对应位置的item属性
     40  *
     41  *  @param indexPath 用来确定每一item具体位置
     42  *
     43  *  @return 用来设置每一个item的属性
     44  */
     45 -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
     46     //NSLog(@"调用了layoutAttributesForItemAtIndexPath");
     47     //    1.确定上左下右间距
     48   
     49     UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 10, 10);
     50    //     2.确定宽度
     51 //        2.1确定列数
     52   
     53 //        2.2确定行间距和列间距
     54     CGFloat rowMargin = 10;
     55     CGFloat colMargin = 10;
     56     
     57     CGFloat itemW = (self.collectionView.frame.size.width - edge.left - edge.right - (column - 1)*colMargin)/column;    
     58 //        3.确定高度
     59 //        3.1获取对应item的模型
     60     LYShopModel *shop = self.shops[indexPath.item];
     61 //    itemW/itemh = shop.width/shop.height;
     62 
     63     CGFloat itemH = shop.height *itemW/shop.width;
     64     
     65 //    CGFloat itmeH = 100+ arc4random_uniform(100);
     66 //        4.确定位置
     67     
     68 //        4.1获取最小的最大y值
     69 //        4.2用一个值来记录最小的最大y值
     70     CGFloat minMaxY = MAXFLOAT;
     71 //        4.3记录最小的最大的y值所在的列号;
     72     NSInteger minMaxCol = 0;
     73     for (int i = 0; i <column; i ++) {
     74         CGFloat maxY = [self.maxYs[i]doubleValue];
     75         if (maxY < minMaxY) {
     76             minMaxY = maxY;
     77             minMaxCol = i;
     78         }
     79     }
     80 //     4.4设置item的x值
     81     CGFloat itemX = edge.left + (itemW + colMargin) *minMaxCol;
     82     CGFloat itemY = minMaxY + rowMargin;
     83 //    5.获取每一个对应位置的item的属性
     84     UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
     85 //    6.设置属性的frame
     86     attr.frame = CGRectMake(itemX, itemY, itemW, itemH);
     87 //    7.累加最小的最大的y值
     88 //    minMaxY = CGRectGetMaxY(attr.frame);
     89     self.maxYs[minMaxCol]= @(CGRectGetMaxY(attr.frame));
     90     
     91     
     92     
     93 //    8.返回属性
     94     return  attr;
     95 
     96 }
     97 /**
     98  *  用来设置给定范围内所有的属性
     99  *
    100  *  @param rect <#rect description#>
    101  *
    102  *  @return <#return value description#>
    103  */
    104 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
    105    // NSLog(@"调用了layoutAttributesForElementsInRect");
    106 //    0.清空原来的所有的值
    107    // [self.maxYs removeAllObjects];
    108 //    1.设置数组的值
    109     for (int i = 0 ; i <column;i ++) {
    110        // [self.maxYs addObject:@(0)];
    111         self.maxYs[i]=@(0);
    112     }
    113     
    114     
    115 //    2.创建可变数组
    116     NSMutableArray *attrs = [NSMutableArray array];
    117     
    118 //
    119 //    3.获取所有的item的属性的个数
    120     NSInteger count = [self.collectionView numberOfItemsInSection:0];
    121 //    4.遍历多次,添加对应的属性值
    122     for (int i = 0; i < count; i ++ ) {
    123         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    124         
    125         UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath];
    126     
    127         [attrs addObject:attr];
    128      //   NSLog(@"%@",attr);
    129         
    130     }
    131     return attrs;
    132 
    133     
    134 }
    135 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    136   //  NSLog(@"调用了shouldInvalidateLayoutForBoundsChange");
    137     return YES;
    138 }
    139 /**
    140  *  用来设置collectionView的滚动范围
    141  *
    142  *  @return <#return value description#>
    143  */
    144 
    145 - (CGSize)collectionViewContentSize{
    146     // NSLog(@"调用了collectionViewContentSize");
    147 //    1.获取最大最大y值
    148     CGFloat maxMaxY = 0;
    149 //    1.1.记录最大的最大y值
    150     if (self.maxYs.count) {
    151          maxMaxY = [self.maxYs[0]doubleValue];
    152         for (int i = 1; i < column; i ++) {
    153             //        1.2获取每一个值
    154             CGFloat maxY = [self.maxYs[i]doubleValue];
    155             if (maxY > maxMaxY) {
    156                 maxMaxY = maxY;
    157             }
    158             
    159         }
    160 
    161     }
    162     
    163    
    164     return CGSizeMake(0, maxMaxY);
    165     
    166 
    167 }
    168 
    169 @end
     1 //LYShopModel文件
     2 #import <Foundation/Foundation.h>
     3 
     4 @interface LYShopModel : NSObject
     5 @property(nonatomic,copy)NSString *icon;
     6 @property(nonatomic,copy)NSString *price;
     7 @property(nonatomic,assign)int height;
     8 @property(nonatomic,assign)int width;
     9 - (instancetype)initWithDict:(NSDictionary *)dict;
    10 + (instancetype)shopWithDict:(NSDictionary *)dict;
    11 
    12 @end
    13 
    14 
    15 
    16 
    17 
    18 #import "LYShopModel.h"
    19 
    20 @implementation LYShopModel
    21 
    22 - (instancetype)initWithDict:(NSDictionary *)dict{
    23     
    24     if (self = [super init]) {
    25         [self setValuesForKeysWithDictionary:dict];
    26     }
    27     return self;
    28 }
    29 + (instancetype)shopWithDict:(NSDictionary *)dict{
    30     
    31     return [[self alloc]initWithDict:dict];
    32 }
    33 
    34 @end
  • 相关阅读:
    SVN服务器搭建(一)
    排序算法二:冒泡排序
    【LeetCode】136. Single Number
    【LeetCode】217. Contains Duplicate
    【LeetCode】189. Rotate Array
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】26. Remove Duplicates from Sorted Array
    【LeetCode】20. Valid Parentheses
    【LeetCode】680. Valid Palindrome II
    【LeetCode】345. Reverse Vowels of a String
  • 原文地址:https://www.cnblogs.com/liyy2015/p/5237083.html
Copyright © 2011-2022 走看看