OC-UICollectionView implements waterfall stream and ocuicollectionview

Source: Internet
Author: User

OC-UICollectionView implements waterfall stream and ocuicollectionview
UICollectionView implements waterfall stream

There are currently two known solutions for implementing waterfall stream in iOS:

This article introduces the second implementation scheme.
First, we need to customizeUICollectionViewLayoutAnd then rewrite the following four methods:

The first method is to perform some initialization operations. This method must first call the implementation of the parent class.
The second method returnsUICollectionViewLayoutAttributesArray
The third method returnsindexPathLocationUICollectionViewLayoutAttributes
The fourth method is to returnUICollectionViewScroll range

How to Implement waterfall stream

First, we need to understand the arrangement of waterfall streams. waterfall streams are some irregular controls distributed on the mobile phone screen, then there must be tall and short ones (just like a person's height, hahaha). When the first row is full, it will continue to be arranged. Where should I put this, = the answer is to put it below the shortest in the first row =, and so on, sort it according to this rule.
Now that we understand this, we should write the code.
First, we create two arrays, one containing the layout attribute of the cell, and the other containing the total height of the current cell.

// C stores the layout attributes of all cells @ property (nonatomic, strong) NSMutableArray * attrsArray; // stores the current height of all columns @ property (nonatomic, strong) NSMutableArray * columnHeights; /** content height */@ property (nonatomic, assign) CGFloat contentHeight;

  

-(Void) prepareLayout {[super prepareLayout]; self. contentHeight = 0; // clear all previously calculated heights, because the method [self. columnHeights removeAllObjects]; for (NSInteger I = 0; I <defacolumcolumncpunt; I ++) {[self. columnHeights addObject: @ (self. edgeInsets. top)];} // put all initialization operations here [self. attrsArray removeAllObjects]; // start to create the layout attribute NSInteger count = [self. collectionView numberOfItemsInSection: 0]; for (NSInteger I = 0; I <count; I ++) {// create the NSIndexPath * indexPath = [NSIndexPath indexPathForItem: I inSection: 0]; // obtain the layout attribute UICollectionViewLayoutAttributes * attrs = [self layoutAttributesForItemAtIndexPath: indexPath]; [self. attrsArray addObject: attrs] ;}}

First, set the cell heightself.edgeInsets.topOtherwise, it will crash. Then obtain the number of items, and then cyclically retrieveUICollectionViewLayoutAttributesAnd add itattsArrayAnd then- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rectThis method directly returnsattrsArrayYou can.

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];    CGFloat collectionViewW = self.collectionView.frame.size.width;    CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right -(self.columnCount - 1) * self.columnMargin) / self.columnCount;    CGFloat h = [self.delegate WaterFlowLayout:self heightForRowAtIndexPath:indexPath.item itemWidth:w];    NSInteger destColumn = 0;    CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];    for (NSInteger i = 0; i < self.columnCount; i++) {        CGFloat columnHeight = [self.columnHeights[i] doubleValue];        if (minColumnHeight > columnHeight) {            minColumnHeight = columnHeight;            destColumn = i;        }    }    CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);    CGFloat y = minColumnHeight;    if (y != self.edgeInsets.top) {        y += self.rowMargin;    }    attrs.frame = CGRectMake(x, y, w, h);    self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));    CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];    if (self.contentHeight < columnHeight) {        self.contentHeight = columnHeight;    }    return attrs;}

The above method is the code used to calculate the position of an item.indexPathOfUICollectionViewLayoutAttributesThe core code is as follows:

NSInteger destColumn = 0;    CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];    for (NSInteger i = 0; i < self.columnCount; i++) {        CGFloat columnHeight = [self.columnHeights[i] doubleValue];        if (minColumnHeight > columnHeight) {            minColumnHeight = columnHeight;            destColumn = i;        }    }    CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);    CGFloat y = minColumnHeight;    if (y != self.edgeInsets.top) {        y += self.rowMargin;    }

First, we get an identifier.destColumnRecord the column and defineminColumnHeightReturns the height of the smallest column.self.columnHeights[0]Here, the default value is the smallest, and then the for loop traversal is performed to obtain the height above the I position. If the value is smaller than the previous minColumnHeight, then the obtained height is the smallest height, and the I value is assigned to destColumn. Then, the value of x is the result of the addition in the code above, and the value of y is to continue to add spacing.

-(CGSize) collectionViewContentSize {// CGFloat maxColumnHeight = [self. columnHeights [0] doubleValue]; // for (NSInteger I = 1; I <DefaultColumnCpunt; I ++) {// obtain the height of column I // CGFloat columnHeight = [self. columnHeights [I] doubleValue]; // if (maxColumnHeight <columnHeight) {// maxColumnHeight = columnHeight; //} return CGSizeMake (0, self. contentHeight + self. edgeInsets. bottom );}

Portal: gitHub

Related Article

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.