• 【代码笔记】自定义布局实现瀑布流


    利用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
  • 相关阅读:
    Java多线程-新特性-有返回值的线程
    Java多线程-新特性-线程池
    java多线程-慎重使用volatile关键字
    Java多线程-线程的调度(守护线程)
    Java多线程-线程的调度(合并)
    Java多线程-线程的调度(让步)
    Java多线程-线程的调度(优先级)
    Java多线程-线程的调度(休眠)
    Java多线程-线程的交互
    let 命令 与 var的区别
  • 原文地址:https://www.cnblogs.com/liyy2015/p/5237083.html
Copyright © 2020-2023  润新知