Exploring UICollectionViewController in iOS development (5) and developing uicollection in ios

Source: Internet
Author: User

Exploring UICollectionViewController in iOS development (5) and developing uicollection in ios

This blog should be regarded as an advanced application of CollectionView. From the perspective of iOS development, UICollectionViewController (1) to today's (5) can be described as a simple and in-depth look at the usage of UICollectionView, these usage not only include the stream layout (UICollectionViewDelegateFlowLayout) in the SDK, but also introduces how to customize your own CollectionView based on your needs. Custom CollectionView is very flexible, and its flexibility also determines its powerful functions. CollectionView is a highly customizable Cell attribute. You can customize the attributes by assigning different Cell attributes.

In the previous blog "iOS development-Snoop UICollectionViewController (4)-a powerful custom waterfall stream", a custom waterfall stream is created through the custom CollectionView, the effect is pretty OK. This blog is another example of using custom CollectionView. The method of custom CollectionView is the same as that of the previous one.

The corresponding method of UICollectionViewLayout, and then set the layout parameters through the delegate callback. The idea of customizing CollectionView is the same, but the specific implementation methods are different. Do you want to write your own custom effects through these two custom CollectionView blogs.

1. Effect display

To put it bluntly, enter the topic of today's blog. below is the running effect of the Demo in today's blog. Although the running effect is made into gif Frame loss, it seems that there are some cards, but it still runs smoothly. When switching an image, a 360-degree rotation is performed and the Cell level is modified. The currently displayed image level is the highest. When moving, if the image to be displayed is not in the center of the screen, a location correction is performed. When you click an image, use the affine transform to enlarge it, and then click to narrow it down. The following describes the implementation scheme in detail.

Ii. Use of the custom Layout

Let's first take a look at how the custom layout is used, and then gradually introduce how it is implemented through usage. This is also a simple process, because it is easier to use. For example, it is easy to drive a car, and it is much more troublesome to build a car. Therefore, in the second part of this blog, we will introduce how to use this custom component.

In fact, the use of the custom Layout of all collectionviews is the same, divided into the following steps:

1. this layout is specified for our CollectionView. This blog's CollectionView is implemented through Storyboard, so we can use Storyboard to specify custom Layout files. If you use pure code, you can specify the layout when CollectionView is instantiated. Below is the Layout file specified by Storyboard. You need to adjust the Layout option to Custom, and the Class option below is the Custom Layout file to be associated, as shown below. I will not repeat the code here, so I will catch the code on the net.

1-(void) viewDidLoad {2 [super viewDidLoad]; 3 4 _ customeLayout = (CustomTransformCollecionLayout *) self. collectionViewLayout; 5 _ customeLayout. layoutDelegate = self; 6}

 

3. In addition to DataSource and Delegate for CollectionView, we also need to implement the layout proxy method. The proxy method to be implemented for this custom layout is as follows. The first is to set the Cell size, that is, the width and height. The second is to set the margin between cells.

 1 #pragma mark <CustomTransformCollecionLayoutDelegate> 2  3 - (CGSize)itemSizeWithCollectionView:(UICollectionView *)collectionView 4                  collectionViewLayout:(CustomTransformCollecionLayout *)collectionViewLayout { 5     return CGSizeMake(200, 200); 6 } 7  8 - (CGFloat)marginSizeWithCollectionView:(UICollectionView *)collectionView 9                     collectionViewLayout:(CustomTransformCollecionLayout *)collectionViewLayout {10     return 10.0f;11 }

 

4. Click Cell to zoom in and zoom out is done by clicking Cell proxy method in UICollectionViewDataSource. I will not go into details here. For details, refer to the link shared on GitHub.

 

3. How to Implement

The following describes how to use the custom component. The third part of this blog introduces how to implement this custom layout.

1. The code in the CustomTransformCollecionLayout header file is as follows. This file defines a protocol. The method in the Protocol is the two proxy methods to be implemented in CollectionView. These proxy methods provide Cell size and margins. The interface of this file defines a proxy object. Of course, this proxy object is of the weak type for the strong reference loop.

1 // 2 // CustomTransformCollecionLayout. h 3 // CustomTransformCollecionLayout 4 // 5 // Created by Mr. luDashi on 15/9/24. 6 // Copyright (c) 2015 ZeluLi. all rights reserved. 7 // 8 9 # import <UIKit/UIKit. h> 10 11 # define SCREEN_WIDTH [[UIScreen mainScreen] bounds]. size. width12 # define SCREEN_HEIGHT [[UIScreen mainScreen] bounds]. size. height13 14 @ class CustomTransformCollecionLayout; 15 16 @ protocol layout <NSObject> 17/** 18 * determine the cell size 19 */20-(CGSize) itemSizeWithCollectionView :( UICollectionView *) collectionView21 collectionViewLayout :( CustomTransformCollecionLayout *) collectionViewLayout; 22 23/** 24 * determine the cell size 25 */26-(CGFloat) rows :( UICollectionView *) collectionView27 collectionViewLayout :( CustomTransformCollecionLayout *) collectionViewLayout; 28 29 @ end30 31 @ interface CustomTransformCollecionLayout: UICollectionViewLayout32 33 @ property (nonatomic, weak) id <CustomTransformCollecionLayoutDelegate> layoutDelegate; 34 35 @ end

 

2. Next we will introduce the code in the CustomTransformCollecionLayout implementation file, that is, the code in. m. The attributes in the extension are as follows. NumberOfSections: this parameter represents the number of sections in CollectionView. NumberOfCellsInSection: represents the number of cells in each Section. ItemSize is the Cell size (width and height). The value of this attribute is provided by the layout proxy method. ItemMargin: This attribute is the Cell margin, which is also provided by the layout proxy method. ItemsX: used to store the X coordinates of each Cell.

1 // 2 // CustomTransformCollecionLayout. m 3 // CustomTransformCollecionLayout 4 // 5 // Created by Mr. luDashi on 15/9/24. 6 // Copyright (c) 2015 ZeluLi. all rights reserved. 7 // 8 9 # import "CustomTransformCollecionLayout. h "10 11 @ interface CustomTransformCollecionLayout () 12 13 @ property (nonatomic) NSInteger numberOfSections; 14 @ property (nonatomic) NSInteger numberOfCellsInSection; 15 @ property (nonatomic) CGSize itemSize; 16 @ property (nonatomic) CGFloat itemMargin; 18 @ property (nonatomic, strong) NSMutableArray * itemsX; 19 20 @ end

 

3. In implementation, we need to override the related methods in UICollectionViewLayout. The method to be rewritten is as follows:

(1) pre-load layout method. This method is executed once when UICollectionView loads data. In this method, it is responsible for calling some initialization functions. The details are as follows.

1 # pragma mark -- Method of UICollectionViewLayout rewriting 2-(void) prepareLayout {3 [super prepareLayout]; 4 5 [self initData]; 6 7 [self initItemsX]; 8}

 

(2). the following method will return ContentSize. To put it bluntly, it is the size of the rolling area of CollectionView.

1/** 2 * This method returns the ContentSize of CollectionView 3 */4-(CGSize) collectionViewContentSize {5 CGFloat width = _ numberOfCellsInSection * (_ itemSize. width + _ itemMargin); 6 return CGSizeMake (width, SCREEN_HEIGHT); 7}

 

(3) The following method binds a UICollectionViewLayoutAttributes object for each Cell to set the attributes of each Cell.

1/*** this method binds a Layout attribute for each Cell ~ 3 */4-(NSArray *) layoutAttributesForElementsInRect :( CGRect) rect {5 6 NSMutableArray * array = [NSMutableArray array]; 7 8 // add cells 9 for (int I = 0; I <_ numberOfCellsInSection; I ++) {10 NSIndexPath * indexPath = [NSIndexPath indexPathForItem: I inSection: 0]; 11 12 UICollectionViewLayoutAttributes * attributes = [self attributes: indexPath]; 13 14 [array addObject: attributes]; 15} 16 return array; 17}

  

(4). the method below is important. Rewrite this method to set different attribute values for each Cell. The transform value is calculated based on the rolling offset of the CollectionView. Therefore, the Cell is rotated when the CollectionView is rolled. The specific implementation scheme adds comments to the code, as shown below:

1/** 2 * set attribute 3 */4 for each Cell (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath :( NSIndexPath *) indexPath {5 6 // get the attributes 7 UICollectionViewLayoutAttributes * attributes = [UICollectionViewLayoutAttributes attributes: indexPath]; 8 9 // get the moving Displacement 10 CGFloat contentOffsetX = self. collectionView. contentOffset. x; 11 // calculate the number of currently displayed Cell12 NSInteger currentIndex = [self countIndexWithOffsetX: contentOffsetX] based on the sliding displacement; 13 // obtain the Cell X coordinate 14 CGFloat centerX = [_ itemsX [indexPath. row] floatValue]; 15 // calculate the Y coordinate of the Cell 16 CGFloat centerY = SCREEN_HEIGHT/2; 17 18 // set the center and size attributes of the Cell 19 attributes. center = CGPointMake (centerX, centerY); 20 attributes. size = CGSizeMake (_ itemSize. width, _ itemSize. height); 21 22 // calculate the current offset (position after sliding-position before sliding) 23 CGFloat animationDistance = _ itemSize. width + _ itemMargin; 24 CGFloat change = contentOffsetX-currentIndex * animationDistance + SCREEN_WIDTH/2-_ itemSize. width/2; 25 26 // make a position correction, because when sliding over half, currentIndex will add one, which is not the index of the Cell shown last time, so subtract a correction 27 if (change <0) {28 change = contentOffsetX-(currentIndex-1) * animationDistance + SCREEN_WIDTH/2-_ itemSize. width/2; 29} 30 31 if (currentIndex = 0 & contentOffsetX <= 0) {32 change = 0; 33} 34 35 // rotation Volume 36 CGFloat temp = M_PI * 2 * (change/(_ itemSize. width + _ itemMargin); 37 38 // The value of the affine transform is 39 attributes. transform = CGAffineTransformMakeRotation (temp); 40 41 // set the zIndex of the currently displayed Cell to a large value 42 if (currentIndex = indexPath. row) {43 attributes. zIndex = 1000; 44} else {45 attributes. zIndex = currentIndex; 46} 47 48 return attributes; 49}View Code

 

(5) to make the Cell rotate with the scroll, You need to override the following method and return YES. If YES is returned for this method, the method (4) is executed again and the attribute value of each Cell is assigned again. So rewrite the following method and return "YES" (the following expression is the same) for motion.

1 // whether the layout should be refreshed when the boundary changes. If YES, the layout information is recalculated when the boundary changes (generally scroll to another place. 2-(BOOL) shouldInvalidateLayoutForBoundsChange :( CGRect) newBounds {3 return! CGRectEqualToRect (newBounds, self. collectionView. bounds); 4}

 

(6). Rewrite the following method to modify the offset of CollectionView scrolling so that the currently displayed Cell appears in the center of the screen. The method is as follows:

1 // modify the Cell position so that the current Cell is displayed in the center of the screen 2-(CGPoint) targetContentOffsetForProposedContentOffset :( CGPoint) proposedContentOffset withScrollingVelocity :( CGPoint) velocity {3 4 5 // number of cells 6 NSInteger index = [self countIndexWithOffsetX: proposedContentOffset. x]; 7 8 CGFloat centerX = index * (_ itemSize. width + _ itemMargin) + (_ itemSize. width/2); 9 10 proposedContentOffset. x = centerX-SCREEN_WIDTH/2; 11 12 return proposedContentOffset; 13}View Code

 

4. The lower part is the method implemented by myself, that is, the function called in the rewrite method, as shown below.

1 # pragma mark-custom method 2/** 3 * calculate the number of cells 4 */5-(NSInteger) countIndexWithOffsetX currently displayed based on the volume of scroll charges: (CGFloat) offsetX {6 return (offsetX + (SCREEN_WIDTH/2)/(_ itemSize. width + _ itemMargin); 7} 8 9/** 10 * initialize the private property, and obtain the configuration parameter 11 */12-(void) initData {13 _ numberOfSections = self through the proxy. collectionView. numberOfSections; 14 15 _ numberOfCellsInSection = [self. collectionView numberOfItemsInSection: 0]; 16 17 _ itemSize = [_ layoutDelegate itemSizeWithCollectionView: self. collectionView collectionViewLayout: self]; 18 19 _ itemMargin = [_ layoutDelegate marginSizeWithCollectionView: self. collectionView collectionViewLayout: self]; 20 21} 22 23/** 24 * calculate the X coordinate of each Cell. 25 */26-(void) initItemsX {27 _ itemsX = [[NSMutableArray alloc] initWithCapacity: _ numberOfCellsInSection]; 28 29 for (int I = 0; I <_ numberOfCellsInSection; I ++) {30 CGFloat tempX = I * (_ itemSize. width + _ itemMargin) + _ itemSize. width/2; 31 [_ itemsX addObject: @ (tempX)]; 32} 33 34 35}

 

Now, the Demo code has been explained. After the above steps, you can write the custom effects in the above animation. The specific code will be shared in github. The sharing link is as follows:

Github Demo link: https://github.com/lizelu/CustomTransformCollecionLayout

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.