IOS control -UICollectionView basic use of detailed explanation (OC)


UICollectionView is introduced from iOS6, and is widely used at present! That’s what a foreigner’s blog says

IOS control -UICollectionView basic use of detailed explanation (OC)
beautiful says HIGO interface

Preliminary comparison with UITableView

  • UITableView should be the most familiar control, and the use of UICollectionView is similar, but it is different, as follows.
    the same point: 1 are driven by datasource and delegate (datasource and delegate, the official document transmission) so when in use must realize data source and proxy protocol method; 2 performance are optimized for recycling. Unlike 1.UITableView, the cell is automatically configured and does not require our layout. But UICollectionView’s cell needs our own layout. So we must deliver a layout parameter when creating the UICollectionView, the system provides and implements a layout style layout (UICollectionViewFlowLayout): water (water distribution of official document transmission). Note: the analysis of 2.UITableViewController FlowLayout on the apple self.view, but UICollectionViewController = = self.tableview; self.view = self.collectionView; only the way of rolling! 3.UITableView is the vertical direction, UICollectionView can scroll vertically or horizontally scrolling; 4.UICollectionView cell only through the registration to determine the identifier reuse. Conclusion: in other words, the layout of UITableView is a special case of the flow layout layout of UICollectionView, analogous to the relation of rectangle to square

Here are a few basic uses (the difficulty is from low to high)

1. UICollectionView common usage (FlowLayout layout)

  • We mentioned above that the UICollectionView and UITableView usage is very similar, let us create a UITableView based entirely on ways to create a UICollectionView (the reader analog UITableView created, data source, proxy, here only to the different aspects of the detailed code reference sample Demo).
  • Error indicating that the layout parameter is missing is as follows:
    IOS control -UICollectionView basic use of detailed explanation (OC)
    lacks a layout parameter error map
  • To resolve the error, we can pass the FlowLayout parameter, or we can override the internal init method. Here we use the override init method to pass layout parameters. It embodies the idea of encapsulation, pass the package layout parameters in the CYXNormalCollectionViewController, foreign only provide external unified method: init method, the code is as follows: – (instancetype) init{/ / UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout layout setting water alloc]init]; / / internal member properties UICollectionViewFlowLayout water layout has the following: @property (nonatomic) CGFloat minimumLineSpacing / * * @property (nonatomic); CGFloat minimumInteritemSpacing; CGSize itemSize; @property (nonatomic) @property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS (8_0); / / defaults to CGSizeZero a non-zero size enables – setting cells that self-size via -preferredLayoutAttributesFittingAttributes: @prop Erty (nonatomic) UICollectionViewScrollDirection scrollDirection default is UICollectionViewScrollDirectionVertical; / / @property (nonatomic) CGSize headerReferenceSize @property (nonatomic); CGSize footerReferenceSize; @property (nonatomic) UIEdgeInsets sectionInset; layout.itemSize = CGSizeMake * / / / define size (100, 100); / / set the minimum line spacing layout.minimumLineSpacing = 2; / / set the vertical spacing of layout.minimumInteritemSpacing = 2; / / set the rolling direction (default vertical scroll) layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; return [self initWithCollectionViewLayout:layout];}
  • Here we use the Xib custom cell, registered [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass through Xib are registered by Xib code / / cell ([CYXNormalCell class]) bundle:nil] forCellWithReuseIdentifier:reuseIdentifier];
  • The initial effect diagram is as follows (here is not detailed implementation, and the rest of the readers refer to the use of UITableView (please click here))
    IOS control -UICollectionView basic use of detailed explanation (OC)
    preliminary renderings

2. novice boot page production

  • A brief description of the new boot page is for almost every application. The purpose is to inform users of the highlights of the application and to attract users. Using the advantages of UICollectionView (recycling) to implement the novice boot page is both simple and efficient. Why not?.
  • Realization of ideas: 1 each cell UICollectionView is set to the size of the screen with the same [UIScreen; layout.itemSize = mainScreen].bounds.size; the 2 is arranged in a horizontal rolling direction, horizontal spacing distance is 0.// layout.minimumLineSpacing = 0; layout.minimumInteritemSpacing = 0; / / set the rolling direction (default roll) layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 3 page scroll mode / open open page self.collectionView.pagingEnabled = YES; / / hide the horizontal scroll bar self.collectionView.showsHorizontalScrollIndicator = NO; self.collectionView.bounces = NO / / cancel spring effect;
  • The following is the effect diagram:
    IOS control -UICollectionView basic use of detailed explanation (OC)
    novice boot page
  • For detailed steps, refer to the sample code:

The 3 picture carousel cycle device

  • Please refer to my previous article (enclosing the code) on the iOS (personal opinion)

4. photo viewer with special effects (custom layout / last)

The following content is divided into two sections:
1> Github example analysis
2> own a small Demo

(1) Github example analysis
  • We often see some CollectionView cell switching cool effects on Github, we analyze the card to switch on Github with 3D animation Demo (RGCardViewLayout) < &gt address please;
  • Here is the renderings of the custom layout Demo effect diagram on
    IOS control -UICollectionView basic use of detailed explanation (OC)
  • Directory structure analysis: the directory structure at a glance, the key is to have a kind of automatic layout (as shown), this class inherits from UICollectionViewFlowLayout (we can guess that he is using the default layout, water) and a – (void) – prepareLayout (NSArray *), layoutAttributesForElementsInRect: (CGRect) rect. We try to annotate the overloaded methods in this class and get the same effect as the regular usage. This shows that the author must have personalized settings within these methods.
    IOS control -UICollectionView basic use of detailed explanation (OC)
  • Key source analysis: first of all, we see that the author did the initialization layout operations for the collectionView in the – (void) prepareLayout method. So we can conclude that rewriting this method is used for initialization (readers can try to modify and change the effect). – (void) prepareLayout [self setupLayout] {[super prepareLayout];}; / / initialize layout – (void) setupLayout {CGFloat = self.collectionView.bounds.size.width * inset (6/64.0f); inset = floor; self.itemSize = (inset) CGSizeMake (self.collectionView.bounds.size.width – (2 *inset), self.collectionView.bounds.size.height * 3/4); self.sectionInset = UIEdgeInsetsMake (0, inset, 0. Inset); self.scrollDirection = UICollectionViewScrollDirectionHorizontal;} then the – (NSArray) layoutAttributesForElementsInRect: (CGRect) rect method should be the most important, similarly, we first comment out inside the personalized settings, leaving only [super layoutAttributesForElementsInRect:rect], we found that the 3D effect is not cool Yes. So you can conclude that this method is personalized to each Cell. Methods: the
    analytic method return value is an array (inside the array storage layout attributes all the elements in the range of rect
    ) the method return value to determine the arrangement of all the elements in the range of Rect (frame)
    UICollectionViewLayoutAttributes *attrs;
    1 a cell corresponding to a UICollectionViewLayoutAttributes
    object 2.UICollectionViewLayoutAttributes object decision cell frame – (NSArray) layoutAttributesForElementsInRect: (CGRect rect) {/ / get the superclass (pipeline layout) has calculated the layout, make personalized modify NSArray *attributes = layoutAttributesForElementsInRect:rect] in the [super based on NSArray [self.collectionView; *cellIndices = indexPathsForVisibleItems]; if (cellIndices.count = = 0) {return attributes}; else if (cellIndices.count = = 1) {mainIndexPath = cellIndices.firstObject; movingInIndexPath = nil;} else if (cellIndices.count > 1) {NSIndexPath *firstIndexPath = cellIndices.firstObject; if (firstIndexPath = = mainIndexPath) {movingInIndexPath} {movingInIndexPath = cellIndices[1]; else = cellIndices.firstObject; mainIndexPath = cellIndices[1];}} difference = self.collectionView.contentOffset.x – previousOffset; previousOffset = self.collectionView.contentOffset.x; / / key code: layout properties of every Cell, and add the 3D effect of for (UICollectionViewLayoutAttrib Utes, *attribute, in, attributes) {[self applyTransformToLayoutAttributes:attribute];} return attributes;}
  • The above key methods have been implemented, but the operation has not found the effect we want, and CollectionViewCell does not deform in real-time. Y so we also need to call the following methods. Analytical method:
    as long as the scroll will call method (NSArray *) layoutAttributesForElementsInRect: (CGRect) rect
    as long as the attributes of the page layout change will call again – (NSArray) layoutAttributesForElementsInRect: (CGRect) rect / / indicate that we want the to redraw as we scroll (BOOL) – shouldInvalidateLayoutForBoundsChange: (CGRect newBounds) {return YES;}
(2) imitate write Demo;
  • After the above analysis of the code, we can simply understand the basic implementation of the custom layout layout, the following can be simulated to write a simple Demo, the effect is as follows.
    IOS control -UICollectionView basic use of detailed explanation (OC)
  • The reference code is as follows (see Github for details)
- (BOOL) shouldInvalidateLayoutForBoundsChange: (CGRect) newBounds {return YES;} - (void) prepareLayout{[super prepareLayout]; self.scrollDirection = UICollectionViewScrollDirectionHorizontal; inset = CGFloat / set margins (self.collectionView.frame.size.width - self.itemSize.width) * 0.5; self.sectionInset = UIEdgeInsetsMake (0, inset, 0, inset);} - (NSArray *) layoutAttributesForElementsInRect: (CGRect) rect super {/ / has calculated the layout of an NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; / / collectionView computing the center value of X CGFloat centerX = self.collectionView.contentOffset.x + 0.5 * self.collectionView.frame.size.width; / / in the original layout is On the basis of the for (UICollectionViewLayoutAttributes *attrs in fine-tuning attributes) {/ / cell x and collectionView center of the center of the x value of delta = ABS distance CGFloat ( - centerX); / / cell values were calculated according to the distance ratio CGFloat scale zoom = 1.2 - Delta / self.collectionView.frame.size.width NSLog (@ ";%f,%f, Delta, scale); / / set the zoom ratio of attrs.transform = CGAffineTransformMakeScale (scale, scale);} return attributes;}

5. waterfall layout (custom layout / next)

  • Waterfall stream layout is very common in many applications, and the effect diagram is as follows:
IOS control -UICollectionView basic use of detailed explanation (OC)
Implementation ideas (Simplified)
  • (1) inherit from UICollectionViewLayout;
  • (2) several methods requiring overloading:
* * * (void) - initialize prepareLayout; / * * return rect in all elements of the layout attributes - * / (NSArray *) layoutAttributesForElementsInRect: (CGRect) rect; / * * return corresponding to the position of indexPath cell layout attributes - * / (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath: (* NSIndexPath) indexPath size; / * * return the contents of collectionView - (CGSize) collectionViewContentSize;

The key calculation code is as follows (see Github in detail)

/ * * * returns the position of the indexPath cell corresponds to the layout attributes - * / (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath: (NSIndexPath * indexPath) {/ / *attrs = UICollectionViewLayoutAttributes to create the layout attributes [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath] collectionView CGFloat collectionViewW; / / width = self.collectionView.frame.size.width; / / set the layout attributes of frame CGFloat (W = collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin / self.columnCount); CGFloat H = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w]; / / find the shortest height of a column of NSInteger DestColumn = 0; CGFloat = minColumnHeight [self.columnHeights[0] doubleValue]; for (NSInteger I = 1; I < self.columnCount; i++) {/ / get the I column height CGFloat columnHeight = [self.columnHeights[i] doubleValue]; if (minColumnHeight > columnHeight) {minColumnHeight = columnHeight; destColumn = I;}} CGFloat = self.edgeInsets.left + destColumn * (x W + self.columnMargin); CGFloat y = minColumnHeight; if (Y! = {y} = self.rowMargin; attrs.frame = CGRectMake (x, y, W, H); / / update the shortest column height self.columnHeights[destColumn] = @ (CGRectGetMaxY (attrs.frame)); / / CGFloa height of the recorded content T columnHeight = [self.columnHeights[destColumn] doubleValue]; if (self.contentHeight, < columnHeight) {self.contentHeight = columnHeight;} return attrs;}

6. layout switching

  • Apple has already been able to think of a shortcut to layout switching for us, only by the following method.
- (void) setCollectionViewLayout: (UICollectionViewLayout *) layout animated: (BOOL) animated transition from one layout to; / / another - (void) setCollectionViewLayout: (UICollectionViewLayout *) layout animated: (BOOL) animated (completion: (void ^ __nullable) (BOOL finished)) completion NS_AVAILABLE_IOS (7_0);

Attached: source GitHub address