Uicollectionview_ios Controls-Detailed (custom layout)

Source: Internet
Author: User

Turn from: https://www.jianshu.com/p/0d1e2e067f6c

Overview

Uicollectionview is introduced from the iOS6, and is now very widely used, very good. That's what a foreigner's blog says. (portal) Beautiful said Higo interface and UITableView comparison

UITableView should be the most familiar control, the use of uicollectionview similar, but there are differences, as described below.
Same point: 1. All are driven by DataSource and delegate (DataSource and delegate Official document transmission), so the data source and proxy protocol method must be implemented when using; 2. The performance of the implementation of the recycling optimization.

Different 1.UITableView cell is the system automatically layout good, do not need our layout. But Uicollectionview's cell needs our own layout. So we have to pass a layout parameter when creating Uicollectionview, the system provides and implements a layout style: Flow layout (uicollectionviewflowlayout) (Flow layout Official document transfer). Note: Apple's resolution of the flowlayout 2.UITableViewController = = Self.view = = Self.tableview; Uicollectionviewcontroller self.view!= The Self.collectionview 3.UITableView scrolling mode can only be vertical, Uicollectionview can scroll either vertically or horizontally; 4. Uicollectionview cell can only be registered to determine the reuse identifier.

Conclusion: In other words, the layout of UITableView is a special case of Uicollectionview flow layout layout, analogous to the relationship between rectangular and square, a few basic usages (difficulty from low to high) are briefly described in 1. Uicollectionview common usage (flowlayout layout) above we mentioned that Uicollectionview is very similar to the use of UITableView, Let's just create a uicollectionview based on the way we create uitableview (please reader analogy uitableview creation way, implement data source, proxy, etc., here just refer to the different aspects, the detailed code can refer to the example demo).

Error, prompt for missing layout parameters, as follows:
Missing layout parameter error map to resolve the error, we can pass the FlowLayout parameter mode, or rewrite the internal init method. Here we use the rewrite Init method to pass the layout parameters. This more embodies the idea of encapsulation, the transfer layout parameters are encapsulated in the Cyxnormalcollectionviewcontroller, external only to provide a unified external method: Init method, the code is as follows:

  -(Instancetype) init{//Set water layout uicollectionviewflowlayout *layout = [[Uicollectionviewflowlayout alloc]init];
     The internal member properties of the Uicollectionviewflowlayout flow layout are as follows:/** @property (nonatomic) cgfloat minimumlinespacing;
     @property (nonatomic) cgfloat minimuminteritemspacing;
     @property (nonatomic) cgsize itemsize; @property (nonatomic) cgsize estimateditemsize Ns_available_ios (8_0); Defaults to cgsizezero-setting a Non-zero size enables cells that self-size via-preferredlayoutattributesfittingattr Ibutes: @property (nonatomic) uicollectionviewscrolldirection scrolldirection;
     Default is Uicollectionviewscrolldirectionvertical @property (nonatomic) cgsize headerreferencesize;
     @property (nonatomic) cgsize footerreferencesize;
     @property (nonatomic) uiedgeinsets sectioninset;
    *///definition size layout.itemsize = cgsizemake (100, 100);
    Set minimum line spacing layout.minimumlinespacing = 2; Set Vertical Spacing layout.minimuminteritemspacing = 2;
    Sets the scrolling direction (default vertical scrolling) layout.scrolldirection = uicollectionviewscrolldirectionhorizontal;
return [self initwithcollectionviewlayout:layout];
 }
Here we use Xib to customize the cell, and the code for registering the cell via Xib is as follows
Register with Xib
  [Self.collectionview registernib:[uinib nibwithnibname:nsstringfromclass ([Cyxnormalcell class]) Bundle:nil] Forcellwithreuseidentifier:reuseidentifier];
The preliminary effect diagram is as follows (this is not implemented in detail here, please refer to the usage of UITableView (please click here)
Preliminary Effect Chart 2. The Novice leads the page to make BriefNovice Guide page, almost every application has, in order to tell users the application of the bright spot, to attract the user's role. Using the advantages of Uicollectionview (recycling) to achieve the Novice Guide page, both simple and efficient, why not? realize the idea:1. Set the size of each cell in the Uicollectionview to be as large as the screen;
Layout.itemsize = [UIScreen mainscreen].bounds.size;
2. Set to horizontal scrolling direction, set horizontal spacing to 0.
Set spacing
    layout.minimumlinespacing = 0;
    layout.minimuminteritemspacing = 0;
Sets the scrolling direction (default vertical scrolling)
    layout.scrolldirection = uicollectionviewscrolldirectionhorizontal;
3. Open Paging scrolling mode
Open paging
    self.collectionView.pagingEnabled = YES;
Hide horizontal scroll bar
    self.collectionView.showsHorizontalScrollIndicator = NO;
    Cancel the spring effect
    self.collectionView.bounces = NO;
here is the effect chart:
Novice Guide Page Implementation detailed steps refer to sample code: Https://github.com/CYXiang/CYXTenMinDemo 3. Picture circulating wheel-seeding devicePlease refer to my previous article (enclosing code), "iOS problem (with personal opinion)" 4. Image browser with effects (custom layout/top)

The following are divided into two sections:
1> GitHub Example Analysis
2> to implement a small demo (1) GitHub example Analysis

We often see in the GitHub on the collectionview of the cell switch cool effect, let us analyze the GitHub on the card switch with 3D animation demo (rgcardviewlayout) < address please point >

Here is the effect chart
Custom layouts on GitHub demo effect diagram

directory Structure Analysis : A clear directory structure, the key is to have an automatic layout class (as shown in the figure), this class inherits from Uicollectionviewflowlayout (we can guess he used the default flow layout), and rewritten-(void) Preparelayout,-(Nsarray *) Layoutattributesforelementsinrect: (CGRect) Rect and other methods. We try to annotate the overloaded methods in this class and get the same effect as normal usage (no screenshots here). This shows that the author must have made personalized settings in these methods.
Directory

Key Source Analysis: First we see that the author has done the initialization layout for CollectionView in the-(void) Preparelayout method. So we can conclude that overriding this method is used for initialization (readers can try to modify, change the effect).

  -(void) preparelayout
  {
     [super preparelayout];
     [Self setuplayout]; Initialize Layout
  }
  -(void) setuplayout
  {
      cgfloat inset  = self.collectionView.bounds.size.width * (6/ 64.0f);
      inset = floor (inset);

      Self.itemsize = 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 this-(Nsarray *) Layoutattributesforelementsinrect: (cgrect) Rect method should be the most important, and similarly, we first comment out the personalized settings, leaving only [super Layoutattributesforelementsinrect:rect], we found that the cool 3D effect is gone. It is therefore possible to conclude that this method is personalized for each cell.

Method Resolution:
The return value of this method is an array (the array contains the layout attributes of all elements within the Rect range).
The return value of this method determines how all elements within the Rect range are arranged (frame)
Uicollectionviewlayoutattributes *attrs;
1. A cell corresponds to a Uicollectionviewlayoutattributes object
The 2.UICollectionViewLayoutAttributes object determines the frame of the cell

-(Nsarray *) Layoutattributesforelementsinrect: (cgrect) Rect {//Get parent class (pipelining layout) already calculated layout, make personalized modification on this basis nsarray *attributes =
  
  [Super Layoutattributesforelementsinrect:rect];
  Nsarray *cellindices = [Self.collectionview 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 = cellindices[1];
          else {movinginindexpath = Cellindices.firstobject;
      Mainindexpath = cellindices[1];
  
  } difference = Self.collectionview.contentoffset.x-previousoffset;
  Previousoffset = Self.collectionview.contentoffset.x; Key code: Take each cell's layout properties and add a 3D effect for (uicollectionviewlayoutattributes *attribute in attributes) {[Self applytransformtolayoutattributes:attribute];
return attributes;
 }
The key methods above have been implemented, but the operation Discovery did not have the effect we wanted, and the Collectionviewcell did not deform in real time. Y so we also need to call the following methods.

Method Resolution:
The scrolling screen calls the method-(Nsarray *) Layoutattributesforelementsinrect: (cgrect) rect
As long as the property of the layout page changes, it is called again-(Nsarray *) Layoutattributesforelementsinrect: (cgrect) Rect this method

Indicate that we want to redraw as we scroll
-(BOOL) Shouldinvalidatelayoutforboundschange: (CGRect) newbounds {
  
   return YES;


  
(2) Imitation writing demo

After the analysis of the code, we can simply understand the basic implementation of the custom layout layout, the following can be imitated to write a simple demo, the effect of the figure below.
Effect chart

The reference code is as follows (see GitHub for details)

-(BOOL) Shouldinvalidatelayoutforboundschange: (CGRect) newbounds {return YES;}
    
    -(void) preparelayout{[Super Preparelayout];
    Self.scrolldirection = Uicollectionviewscrolldirectionhorizontal;
    Set inner margin cgfloat inset = (self.collectionview.frame.size.width-self.itemsize.width) * 0.5;
    
Self.sectioninset = Uiedgeinsetsmake (0, inset, 0, inset);  }-(Nsarray *) Layoutattributesforelementsinrect: (cgrect) Rect {//Get super already calculated layout properties Nsarray *attributes = [super
    
    Layoutattributesforelementsinrect:rect]; Calculates the X-value CGFloat CenterX = self.collectionview.contentoffset.x + Self.collectionView.frame.size.wid of the CollectionView most central point
    

    th * 0.5; On the basis of the original layout properties, fine-tune for (uicollectionviewlayoutattributes *attrs in attributes) {//cell central point x and Collectionvie
        W Most central point of the X-value spacing cgfloat delta = ABS (Attrs.center.x-centerx);
    
  Calculates the scaling ratio of the cell based on the spacing value cgfloat scale = 1.2-delta/self.collectionview.frame.size.width;      NSLog (@ "%f,%f", Delta,scale);
    Set Scaling Scale Attrs.transform = cgaffinetransformmakescale (scale, scale);
    
return attributes;

 }
5. Waterfall Flow Layout (custom layout/bottom)Waterfall flow layout is very common in many applications, the effect chart is as follows: Effect chart Realization Idea (simplification)(1) inheriting from Uicollectionviewlayout; (2) Several methods that need to be overloaded:
 * * Initialization
//(void) preparelayout;
/
 * Returns the layout properties of all elements in rect *
 *
(Nsarray *) Layoutattributesforelementsinrect: (cgrect) rect;
 * * Returns the layout properties of the cell corresponding to the position of Indexpath * *
(uicollectionviewlayoutattributes *) Layoutattributesforitematindexpath: (Nsindexpath *) Indexpath;
 * * Returns the dimensions
of the CollectionView content * * -(cgsize) collectionviewcontentsize;

The key calculation code is as follows (see GitHub for details)
/** * Returns the layout properties of the cell corresponding to the Indexpath position/-(Uicollectionviewlayoutattributes *) Layoutattributesforitematindexpath: ( Nsindexpath *) Indexpath {//Create layout properties Uicollectionviewlayoutattributes *attrs = [Uicollectionviewlayoutattributes LA
    
    Youtattributesforcellwithindexpath:indexpath];
    
    CollectionView width cgfloat collectionvieww = self.collectionView.frame.size.width;  Sets the frame cgfloat w = (Collectionvieww-self.edgeinsets.left-self.edgeinsets.right-(self.columncount-1) for layout properties *
    Self.columnmargin)/Self.columncount;
    
    CGFloat h = [Self.delegate waterflowlayout:self heightForItemAtIndex:indexPath.item itemwidth:w];
    Find out which row of the shortest height nsinteger destcolumn = 0;
    CGFloat mincolumnheight = [self.columnheights[0] doublevalue]; for (Nsinteger i = 1; i < Self.columncount; i++) {//Get the height of column i cgfloat columnheight = [Self.columnheigh
        
        Ts[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);
    
    Update shortest that column of height self.columnheights[destcolumn] = @ (Cgrectgetmaxy (attrs.frame));
    The height of the record content cgfloat columnheight = [Self.columnheights[destcolumn] doublevalue];
    if (Self.contentheight < columnheight) {self.contentheight = Columnheight;
return attrs;

 }
6. Layout SwitchApple has already figured out a shortcut to the layout switch, which you can do only through the following methods.
-(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);

attachment: source GitHub address

Author: developer_cyx
Link: https://www.jianshu.com/p/0d1e2e067f6c
Source: Jianshu
Copyright belongs to the author. Commercial reprint please contact the author to obtain authorization, non-commercial reprint please indicate the source.

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.