天天看点

iOS CollectionView the completed guide(2th) chapter 04 Example Dimensions

Today, I learned the iOS CollectionView the completed guide(2th) chapter 04

there is one demo project Called Dimensions. this project is for demonstrating how to add  layoutAttributes

for customizing the collectionView. Such as the CollectionViewCell's contentView has a imageView. how to set the imageView's contentMode for different value(UIViewContentModeScaleAspectFill, UIViewContentModeScaleAspectFit) .the solution is below.

1. define a new enum for ContentMode

typedef enum : NSUInteger{

    AFCollectionViewFlowLayoutModeAspectFit,    //Default

    AFCollectionViewFlowLayoutModeAspectFill

}AFCollectionViewFlowLayoutMode;

2.Subclass UICollectionViewLayoutAttributes

@interface AFCollectionViewLayoutAttributes : UICollectionViewLayoutAttributes

@property (nonatomic, assign) AFCollectionViewFlowLayoutMode layoutMode;

@end

3.Subclass UICollectionViewFlowLayout

@interface AFCollectionViewFlowLayout : UICollectionViewFlowLayout

@property (nonatomic, assign) AFCollectionViewFlowLayoutMode layoutMode;

@end

4.Override  +(Class)layoutAttributesClass in superClass UICollectionViewFlowLayout

+(Class)layoutAttributesClass

{

    // Important for letting UICollectionView know what kind of attributes to use.

    return [AFCollectionViewLayoutAttributes class];

}

5.Override Methods 

#pragma mark Cell Layout

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

{

    NSArray *attributesArray = [super layoutAttributesForElementsInRect:rect];

    for (AFCollectionViewLayoutAttributes *attributes in attributesArray)

    {

        [self applyLayoutAttributes:attributes];

    }

    return attributesArray;

}

#pragma mark - Private Helper Methods

-(void)applyLayoutAttributes:(AFCollectionViewLayoutAttributes *)attributes

{

    // Check for representedElementKind being nil, indicating this is a cell and not a header or decoration view

    if (attributes.representedElementKind == nil)

    {

        // Pass our layout mode onto the layout attributes

        attributes.layoutMode = self.layoutMode;

        if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:layoutModeForItemAtIndexPath:)])

        {

            attributes.layoutMode = [(id<AFCollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView layout:selflayoutModeForItemAtIndexPath:attributes.indexPath];

        }

    }

}

#pragma mark - Overridden Properties

-(void)setLayoutMode:(AFCollectionViewFlowLayoutMode)layoutMode

{

    // Update our backing ivar...

    _layoutMode = layoutMode;

    // then invalidate our layout.

    [self invalidateLayout];

}

#pragma mark - Overide -(void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes in UICollectionViewCell

#pragma mark - Overridden Methods

-(void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes

{

    [super applyLayoutAttributes:layoutAttributes];

    // Important! Check to make sure we're actually this special subclass.

    // Failing to do so could cause the app to crash!

    if (![layoutAttributes isKindOfClass:[AFCollectionViewLayoutAttributes class]])

    {

        return;

    }

    AFCollectionViewLayoutAttributes *castedLayoutAttributes = (AFCollectionViewLayoutAttributes *)layoutAttributes;

    layoutMode = castedLayoutAttributes.layoutMode;

    [self setImageViewFrame];

}

Conclusion: 1. be aware of the difference between the UIViewContentModeScaleAspectFill and UIViewContentModeScaleAspectFit

    2. be aware of the bounds, frame, center of UIView

    3. know how to calculate the aspectRatio according to the imageView.image.size

    4. know the layoutAttributesForElementInRect from UICollectionViewFlowLayout and  -(void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes in UICollectionViewCell  was called by iOS before the 

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath.