I have explained in detail the use of CollectionView and the design of custom Collectionviewcell in the previous blog, can refer to the "iOS development actual combat--collectionview Click event and the keyboard hide combination case" "iOS Advanced Development- CollectionView Modify cell text and model refactoring this blog. But today we still need to talk about a small hole in the CollectionView implementation, which I recently found on the internet when many developers often make mistakes, so I think it is necessary to have a good talk.
How is the spacing between two cells set in a CollectionView control? This is a very common problem. When we search this question on the Internet, many people tell you to use uicollectionviewdelegateflowlayout this agent in the Minimuminteritemspacingforsectionatindex method to set. In fact, this is completely wrong, when you really use this method to set the spacing, find out how to set up their own needs, really is very different. This blog is going to solve this problem, the sample code is uploaded to Https://github.com/chenyufeng1991/SpaceOfCollectionView.
(1) First customize a Collectionviewcell, inherit from Uicollectionviewcell. Put a picture fill in this cell, which is defined as Customcollectionviewcell.
The CustomCollectionViewCell.h file is as follows:
#import <UIKit/UIKit.h> #define SCREEN_WIDTH ([[UIScreen mainscreen] bounds].size.width) #define CELL_WIDTH01 ( SCREEN_WIDTH-80)/3#define cell_width02 70@interface customcollectionviewcell:uicollectionviewcell@property ( Nonatomic, strong) Uiimageview *imageview; @end
The customcollectionviewcell.m file is as follows:
#import "CustomCollectionViewCell.h" #import "Masonry.h" @implementation customcollectionviewcell-(Instancetype) initWithFrame: (cgrect) frame{self = [Super Initwithframe:frame]; if (self) { Self.imageview = [[Uiimageview alloc] Initwithframe:cgrectmake (0, 0, cell_width02, cell_width02)]; [self addSubview:self.imageView]; The picture fills the entire cell [Self.imageview mas_makeconstraints:^ (Masconstraintmaker *make) { make.edges.equalTo (self); }] ; } return self;} @end
The macro definition above Screen_width represents the screen width. Cell_width01 and cell_width02 can be used to set the cell's width and height.
(2) My main file is mainviewcontroller.m, first I need to declare three agents:
Uicollectionviewdelegate,
Uicollectionviewdatasource,
Uicollectionviewdelegateflowlayout
(3) Declare two properties in MAINVIEWCONTROLLER.M:
@property (nonatomic, strong) Uicollectionview *collectionview; @property (nonatomic, strong) Nsmutablearray *COLLARR;
(4) Macros define several variables:
#define Array_count 10#define minimum_item_space 5#define minimum_line_space 5
Array_count is the number of cells;
Minimum_item_space is to set the minimum spacing between cells (and so I explain this concept)
Minimum_line_space is to set the spacing between each line.
(5) UI layout
-(void) configui{//CollectionView Self.collarr = [[Nsmutablearray alloc] init]; for (int i = 0; i < Array_count; i++) {[Self.collarr addobject:[uiimage imagenamed:@ "Beauty"]]; } uicollectionviewflowlayout *flowlayout = [[Uicollectionviewflowlayout alloc] init]; [FlowLayout setscrolldirection:uicollectionviewscrolldirectionvertical];//CollectionView Scroll direction, only two Select one//Initialize, You can not set the width height through the following mas_makeconstraints automatic layout. Self.collectionview = [[Uicollectionview alloc] Initwithframe:cgrectmake (0, +, screen_width, cell_width02 * 2) Collectionviewlayout:flowlayout]; Self.collectionView.bounces = NO; [Self.collectionview Registerclass:[customcollectionviewcell class] forcellwithreuseidentifier:@ "CollectionCell"] ; Self.collectionView.delegate = self; Self.collectionView.dataSource = self; [Self.view AddSubview:self.collectionView]; [Self.collectionview mas_makeconstraints:^ (Masconstraintmaker *make) {Make.top.equalTo (Self.view). Offset (64); Make.left.equalTo (Self.view); Make.right.equalTo (Self.view); Make.height.equalTo (@ (CELL_WIDTH02 * 2)); }];}
The number of cells can be set by macro definition Array_count.
Here AutoLayout I use masonry for automatic layout, about the use of Masonry can refer to the AutoLayout third-party library masonry introduction and practice.
Here I set the width of the uicollection to the screen width, the height is 2 * cell_width02.
Uicollectionviewflowlayout is the layout of the CollectionView internal cell that must be set.
(6) method rewrite in Uicollectionviewdatasource agent:
#pragma mark-uicollectionviewdatasource-(Nsinteger) CollectionView: (Uicollectionview *) CollectionView Numberofitemsinsection: (nsinteger) section{ return self.collArr.count;} -(Uicollectionviewcell *) CollectionView: (Uicollectionview *) CollectionView Cellforitematindexpath: (NSIndexPath *) indexpath{ Customcollectionviewcell *cell = [CollectionView dequeuereusablecellwithreuseidentifier:@] Collectioncell "Forindexpath:indexpath"; Reuse cell if (cell = = nil) { //When reusing cell is empty, create a new cell cell = [[Customcollectionviewcell alloc] init]; } cell.imageView.image = Self.collarr[indexpath.row]; return cell;}
Numberofitemsinsection is to set the number of cells in the section, returning the number of arrays, which is actually the Array_count macro definition.
The Cellforitematindexpath is assigned to the cell.
(7) Override of method in Uicollectionviewdelegateflowlayout agent:
#pragma mark-uicollectionviewdelegateflowlayout//The method is to set the cell's size-(cgsize) CollectionView: (Uicollectionview *) CollectionView layout: (uicollectionviewlayout*) collectionviewlayout Sizeforitematindexpath: (NSIndexPath *) indexpath{return Cgsizemake (cell_width02, cell_width02);} The method is to set a section of the upper left lower right margin-(uiedgeinsets) CollectionView: (Uicollectionview *) CollectionView layout: ( uicollectionviewlayout*) collectionviewlayout Insetforsectionatindex: (nsinteger) section{//Note that there is a +64 margin on top here by default, Because the status bar + navigation bar is 64. Because we often put [[UIScreen mainscreen] bounds] as the CollectionView area, so the Apple API default to +64 Edgeinsets, here is actually a pit, be sure to pay attention. Here I do not use this margin, so top minus 64//So it is necessary to consider that you are putting collection from the upper left corner of the screen (0,0) Release vessel is (0,64) start to put. Return Uiedgeinsetsmake (-64, 0, 0, 0);} The minimum spacing between two cells is calculated automatically by the API, and the cell will wrap only if the spacing is less than this value-(cgfloat) CollectionView: (Uicollectionview *) CollectionView Layout: (uicollectionviewlayout*) collectionviewlayout Minimuminteritemspacingforsectionatindex: (NSInteger) section{return minimum_item_space;} The smallest room between two rowsDistance-(CGFloat) CollectionView: (Uicollectionview *) CollectionView layout: (uicollectionviewlayout*) Collectionviewlayout Minimumlinespacingforsectionatindex: (nsinteger) section{return minimum_line_space;}
--The Sizeforitematindexpath method is to set the cell's width height, where I set it to cell_width02;
--The Insetforsectionatindex method is to set the inner margin of a section in the CollectionView;
--The Minimuminteritemspacingforsectionatindex method is to set the minimum padding between cells (which I'll explain in detail below);
--The Minimumlinespacingforsectionatindex method is to set the distance between each line;
(8) After completing the above code, the effect of the implementation is as follows:
。
---------------------------------------------------------------------------------------------------------(make a split line , in fact, the above is the cushion, the following formal how to set the cell between the margin)
In fact, the spacing between cells is not manually set by us, and there is no way to set it manually, which is calculated by the system. The method is calculated as follows:
CollectionView width: collectionwidth,
A cell width: cellwidth,
Number of cells in a row: N,
Cell spacing: SpaceX,
Minimum cell spacing: minimumx
The formula is as follows: SpaceX = Collectionwidth-cellwidth * N (n is a positive integer); When SpaceX >= minimumx, n increments, which means that the number of cells in a row increases. The system detects that when a cell is added, SpaceX < minimumx (the actual spacing must not be less than the minimum spacing), the cell wraps, so n takes the maximum value within the allowable range. Thus, the spacing of a fixed Collectionview,cell is determined by the width of the cell.
In my example above, it was tested under the 5s simulator, with a screen width of 320,cell width of 70,minimuminteritemspacingforsectionatindex method set to the minimum cell spacing of 5, so a row can only drop 4 cells , and the spacing between the cells = (320-70*4)/3 = 13.33 > 5. And can't put 5, because 5 * x > 320. Of course, the cell is unlikely to be 3 because the maximum value that can be set is 4. I'm here to verify that this is correct:
。
By verifying that our calculation is correct, because it is twice times the pixel: so 2*13 = 26.
Well, to illustrate the correctness of my statement again, the return value of the Minimuminteritemspacingforsectionatindex method can be any positive integer below 13, and the last UI that runs is the same. Because when cell=4, the system calculates 13.33 is always greater than the Minimuminteritemspacingforsectionatindex return value.
Now modify the code, Minimuminteritemspacingforsectionatindex return a value of 14, rerun the program, the UI effect is as follows:
The minimum spacing between two cells is calculated automatically by the API, and the cell will wrap only if the spacing is less than this value-(cgfloat) CollectionView: (Uicollectionview *) CollectionView Layout: (uicollectionviewlayout*) collectionviewlayout Minimuminteritemspacingforsectionatindex: (NSInteger) section{ return 14.0f;}
。
You can see that there are only 3 cells in a row. Because when a line cell=4, the spacing 13.33 is less than the minimum spacing I set 14, so the system has to reduce a cell to meet the minimum spacing requirement. Now calculate the spacing: (320-3 *)/2 = > 14 minimum spacing, meet the criteria, pass to verify:
。
The actual proof of the calculation is still correct.
Now everyone should understand the meaning of Minimuminteritemspacingforsectionatindex this method, and also know how to adjust the cell spacing. So to sum up, for the control of the number of cells in CollectionView and cell spacing, only through the cell's width and minimuminteritemspacingforsectionatindex set the minimum spacing to complete, Rather than manually set it up by code, the calculation task is given to the system.
Space settings for cells in the iOS development combat--collectionview