[Code Note] custom Layout for waterfall flow and waterfall Layout

Source: Internet
Author: User

[Code Note] custom Layout for waterfall flow and waterfall Layout

The file directory is as follows:

 

 

The animation is as follows:

1 // ViewController file 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 @ end13 14 @ implementation ViewController15 static NSString * ID = @ "water"; 16 17-(NSArray *) shops {18 19 if (_ shops = nil) {20 // 1. read File 21 NSString * path = [[NSBundle mainBundle] pathForResource: @ "1. plist "ofType: nil]; 22 NSArray * dictArray = [NSArray arrayWithContentsOfFile: path]; 23 // 2. dictionary conversion model 24 bytes * 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. custom Layout 42 LYWaterFlowLayout * waterFlowLayout = [[LYWaterFlowLayout alloc] init]; 43 // 0. 1. pass the external array to the internal 44 waterFlowLayout. shops = self. shops; 45 46 // 1. create collectionView47 UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame: CGRectMake (0, 0, self. view. frame. size. width, self. view. frame. size. height) collectionViewLayout: waterFlowLayout]; 48 // 2. set the data source 49 collectionView. dataSource = self; 50 // 3. set proxy 51 // collectionView. delegate = self; 52 53 54 // 3. add 55 [self. view addSubview: collectionView]; 56 // 4. register cell57 [collectionView registerNib: [UINib nibWithNibName: @ "LYWaterCell" bundle: nil] region: 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. create cell77 78 LYWaterCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier: ID forIndexPath: indexPath]; 79 // 2. value: 80 // 81 // cell. backgroundColor = [UIColor redColor]; 82 // 2.1 obtain the model 83 LYShopModel * shop = self. shops [indexPath. item]; 84 cell. shop = shop; 85 86 cell. indexPath = indexPath; 87 // 3. return cell88 return cell; 89 90 91} 92 93 @ end
1 // LYWaterCell file 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 @ end11 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 @ end25 @ implementation LYWaterCell26-(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 file 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 * is used to set the item attribute of each corresponding position 40*41 * @ param indexPath is used to determine the specific position of each item 42*43 * @ return is used to set each item attributes 44 */45-(UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath :( NSIndexPath *) indexPath {46 // NSLog (@ "layoutAttributesForItemAtIndexPath"); 47 // 1. determine the upper left bottom right margin 48 49 UIEdgeInsets edge = UIEdgeInsetsMake (10, 10, 10); 50 // 2. determine width 51 // 2.1 determine Number of columns 52 53 // 2.2 determine row spacing and column spacing 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. determine the height 59 // 3.1 obtain the corresponding item Model 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. determine the position 67 68 // 4.1 obtain the minimum maximum y Value 69 // 4.2 Use a value to record the minimum maximum y value 70 CGFloat minMaxY = MAXFLOAT; 71 // column number of the smallest and largest y value in the 4.3 record; 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 set item x value 81 CGFloat itemX = edge. left + (itemW + colMargin) * minMaxCol; 82 CGFloat itemY = minMaxY + rowMargin; 83 // 5. obtain the attributes of each item in the corresponding position. 84 UICollectionViewLayoutAttributes * attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath: indexPath]; 85 // 6. set the frame 86 attr of the attribute. frame = CGRectMake (itemX, itemY, itemW, itemH); 87 // 7. the maximum value of y is 88 // minMaxY = CGRectGetMaxY (attr. frame); 89 self. maxYs [minMaxCol] = @ (CGRectGetMaxY (attr. frame); 90 91 92 93 // 8. return attribute 94 return attr; 95 96} 97/** 98 * is used to set all attributes within the specified range 99*100 * @ param rect <# rect description #> 101*102 * @ return <# return value description #> 103 */104-(NSArray <UICollectionViewLayoutAttributes *> *) layoutAttributesForElementsInRect :( CGRect) rect {105 // NSLog (@ "layoutAttributesForElementsInRect"); 106 // 0. clear all original values 107 // [self. maxYs removeAllObjects]; 108 // 1. set the value of the array to 109 for (int I = 0; I <column; I ++) {110 // [self. maxYs addObject: @ (0)]; 111 self. maxYs [I] = @ (0); 112} 113 114 115 // 2. create a variable array 116 NSMutableArray * attrs = [NSMutableArray array]; 117 118 119 // 3. obtain the number of attributes of all items. 120 NSInteger count = [self. collectionView numberOfItemsInSection: 0]; 121 // 4. traverse multiple times and add the corresponding property value 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 128 [attrs addObject: attr]; // NSLog (@ "% @", attr ); 129 130} 131 return attrs; 132 133 134} 135-(BOOL) returns :( CGRect) newBounds {136 // NSLog (@ "shouldInvalidateLayoutForBoundsChange" called); 137 return YES; 138} 139/** 140 * is used to set the rolling range of collectionView to 141*142 * @ return <# return value description #> 143 */144 145-(CGSize) collectionViewContentSize {146 // NSLog (@ "collectionViewContentSize called"); 147 // 1. obtain the maximum y value 148 CGFloat maxMaxY = 0; 149 // 1. 1. the maximum y value of a record is 150 if (self. maxYs. count) {151 maxMaxY = [self. maxYs [0] doubleValue]; 152 for (int I = 1; I <column; I ++) {153 // 1.2 get each value 154 CGFloat maxY = [self. maxYs [I] doubleValue]; 155 if (maxY> maxMaxY) {156 maxY = maxY; 157} 158 159 160} 161 162 163 return CGSizeMake (0, maxMaxY ); 165 166 167} 168 169 @ end
1 // LYShopModel file 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 @ end13 14 15 16 17 18 # import "LYShopModel. h "19 20 @ implementation LYShopModel21 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

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.