UICollectionView的横线问题

本文主要介绍如何通过自定义UICollectionViewFlowLayout解决显示横线的问题。在`prepareLayout`方法中进行初始化设置,在`layoutAttributesForElementsInRect:`中返回需要布局的元素,特别是`layoutAttributesForDecorationViewOfKind:atIndexPath:`方法,用于处理装饰视图(横线)的布局属性。通过重写这些方法,可以实现横线的定制或移除。
摘要由CSDN通过智能技术生成

一、自定义Flowlayout

 UICollectionViewFlowLayout类是最重要的,整个横线就是从这个类里控制的,这里的横线是个横线的 图片加载到UICollectionview的decoration View上的decoration View

-(void)prepareLayout

实例化视图或更新视图或者查询视图信息之前,被自动调用,设定一些必要的layout的结构和初始需要参数等

- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect

1、返回在rect中的所有的元素的布局属性,是包含UICollectionViewLayoutAttributes的array.

2、UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttribures:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

 返回对应于indexPath的位置的cell的布局属性

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath

 返回对应于indexPath的位置的装饰视图的布局属性,没有装饰视图可以不重载此方法

代码:

(重点是自定义的FlowLayout)

GridLayout.h

<pre name="code" class="objc">//gridView视图对应的UICollectionViewLayout,向UICollectionView提供布局信息,
//包括cell的布局信息,也包括Supplementary Views(追加视图,类似与headerView或者FooterView)和Decoration Views(装饰视图,用作背景展示)的布局信息。

@interface GridLayout : UICollectionViewFlowLayout

@property (nonatomic, strong) NSDictionary *shelfRects;

- (id)initForIpad;

- (id)initForIphone;

@end 

 


GridLayout.m

#import "GridLayout.h"
#import "ShelfView.h"
#import "GridLayoutAttributes.h"
@implementation GridLayout

/**
 为Ipad初始化
 @author maguang
 @param parameter
 @return result
 */
- (id)initForIpad
{
    if (self = [super init]) {
        self.scrollDirection = UICollectionViewScrollDirectionVertical;//垂直滚动
        self.itemSize = (CGSize){150,200};//cell的大小
        self.sectionInset = UIEdgeInsetsMake(30, 30, 30, 30);//定义每个cell的边缘,top,left,bottom,right
        //根据程序运行环境(Ipad或者Iphone)定义headerView的大小
        //        self.headerReferenceSize = [[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad?(CGSize){50,50}:(CGSize){43,43};
        //        //定义footView的大小
        //        self.footerReferenceSize = (CGSize){44,44};
        //横排cell之间最小间隔(对应左右)
        self.minimumInteritemSpacing = 36;
        //竖排cell之间最小间隔(对应上下)
        self.minimumLineSpacing = 36;
        
        //注册DecorationView
        [self registerClass:[ShelfView class] forDecorationViewOfKind:[ShelfView kind]];
    }
    return self;
}

/**
 为iphone初始化
 @author maguang
 @param parameter
 @return result
 */
- (id)initForIphone
{
    if (self = [super init]) {
        self.scrollDirection = UICollectionViewScrollDirectionVertical;//垂直滚动
        self.itemSize = (CGSize){80,120};//cell的大小
        self.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);//定义每个cell的边缘,top,left,bottom,right
        //根据程序运行环境(Ipad或者Iphone)定义headerView的大小
        //        self.headerReferenceSize = [[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad?(CGSize){50,50}:(CGSize){43,43};
        //        //定义footView的大小
        //        self.footerReferenceSize = (CGSize){44,44};
        //横排cell之间最小间隔(对应左右)
        self.minimumInteritemSpacing = 20;
        //竖排cell之间最小间隔(对应上下)
        self.minimumLineSpacing = 20;
        
        //注册DecorationView
        [self registerClass:[ShelfView class] forDecorationViewOfKind:[ShelfView kind]];
    }
    return self;
}

/**
 重写父类方法,提供一个通用类以来初始化MyLayoutAttributes的实例
 @param parameter
 @return result
 */
+ (Class)layoutAttributesClass
{
    return [GridLayoutAttributes class];
}

/**
 实例化视图或更新视图或者查询视图信息之前,被自动调用,设定一些必要的layout的结构和初始需要参数等。
 @param parameter
 @return result
 */
- (void)prepareLayout
{
    [super prepareLayout];
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
        //calculate where shelves go in a vertiacl layout
        NSInteger sectionCount = [self.collectionView numberOfSections];
        CGFloat y = 0;
        //有效宽度
        CGFloat availableWidth = self.collectionViewContentSize.width - (self.sectionInset.left+self.sectionInset.right);
        //向下取整,水平方向cell的列数
        int itemAcross = floorf((availableWidth + self.minimumInteritemSpacing) / (self.itemSize.width + self.minimumInteritemSpacing));
        
        for (int section = 0; section < sectionCount; section++) {
            y += self.headerReferenceSize.height;
            y += self.sectionInset.top;
            
            //获取指定section下cell的个数
            NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
            //获取指定section,垂直方向cell的行数
            int rows = ceilf(itemCount/(float)itemAcross);
            
            //for循环,设置线的位置,线的坐标为(0,y+5),线的高度为2
            for (int row = 0; row < rows; row++) {
                y += self.itemSize.height;
                dictionary[[NSIndexPath indexPathForItem:row inSection:section]] = [NSValue valueWithCGRect:CGRectMake(0, y+5, self.collectionViewContentSize.width, 4)];
                if (row < rows - 1) {
                    y += self.minimumLineSpacing;
                }
            }
            y += self.sectionInset.bottom;
            y += self.footerReferenceSize.height;
        }
    }else{
        //Calculate where shelves go in a horizontal layout
        CGFloat y = self.sectionInset.top;
        //有效高度
        CGFloat availableHeight = self.collectionViewContentSize.height - (self.sectionInset.top + self.sectionInset.bottom);
        //向下取整,垂直方向cell的行数
        int itemsAcross = floorf((availableHeight + self.minimumInteritemSpacing) / (self.itemSize.height + self.minimumInteritemSpacing));
        //
        CGFloat interval = ((availableHeight - self.itemSize.height) / (itemsAcross <= 1?1:itemsAcross - 1)) - self.itemSize.height;
        
        for (int row = 0; row < itemsAcross; row++) {
            y += self.itemSize.height;
            dictionary[[NSIndexPath indexPathForItem:row inSection:0]] = [NSValue valueWithCGRect:CGRectMake(0, y+5, self.collectionViewContentSize.width, 4)];
            
            y += interval;
        }
    }
    self.shelfRects = [NSDictionary dictionaryWithDictionary:dictionary];
}

/**
 1、返回在rect中的所有的元素的布局属性,是包含UICollectionViewLayoutAttributes的array.
 2、UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttribures:
    (1)、layoutAttributesForCellWithIndexPath:
    (2)、layoutAttributesForSupplementaryViewOfKind:withIndexPaht:
    (3)、layoutAttributesForDecorationViewOfKind:withIndexPath:
 @param parameter
 @return result
 */
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes *attributes in array) {
        attributes.zIndex = 1;
        //if (attributes.representedElementCategory != UICollectionElementCategoryCell)
        /*if (attributes.representedElementCategory != UICollectionElementCategorySupplementaryView || [attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader])
         attributes.alpha = 0.5;
         else if (attributes.indexPath.row > 0 || attributes.indexPath.section > 0)
         attributes.alpha = 0.5; // for single cell closeup*/
        
        if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal && attributes.representedElementCategory == UICollectionElementCategorySupplementaryView) {
            attributes.transform3D = CATransform3DMakeRotation(-90 * M_PI / 180, 0, 0, 1);
            attributes.size = CGSizeMake(attributes.size.height, attributes.size.width);
        }
        
//        if (attributes.representedElementCategory == UICollectionElementCategorySupplementaryView && [attributes isKindOfClass:[MyLayoutAttributes class]]) {
//            MyLayoutAttributes *myAttributes = (MyLayoutAttributes*)attributes;
            myAttributes.headerTextAlignment = NSTextAlignmentLeft;
//        }
    }
    
    //Add our decoration Views(shelves)
    NSMutableArray *aArray = [array mutableCopy];
    [self.shelfRects enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (CGRectIntersectsRect([obj CGRectValue], rect)) {
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[ShelfView kind] withIndexPath:key];
            attributes.frame = [obj CGRectValue];
            NSLog(@"第一个x= %f,y = %f,with = %f,height = %f",attributes.frame.origin.x,attributes.frame.origin.y,attributes.frame.size.width,attributes.frame.size.height);
            attributes.zIndex = 0;
//            attributes.alpha = 0.5;
            [aArray addObject:attributes];
        }
    }];
    array = [NSArray arrayWithArray:aArray];
    return array;
}

/**
 返回对应于indexPath的位置的cell的布局属性
 @param indexPath - cell的位置
 @return result
 */
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
    attributes.zIndex = 1;
    return attributes;
}

/**
 返回对应于indexPath的位置的装饰视图的布局属性,没有装饰视图可以不重载此方法
 @param parameter
 @return result
 */
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath
{
    id shelfRect = self.shelfRects[indexPath];
    if (!shelfRect) {
        return nil;
    }
    
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[ShelfView kind] withIndexPath:indexPath];
    attributes.frame = [shelfRect CGRectValue];
    NSLog(@"第二个x= %f,y = %f,with = %f,height = %f",attributes.frame.origin.x,attributes.frame.origin.y,attributes.frame.size.width,attributes.frame.size.height);
    attributes.zIndex = 0;//层次关系,O层
    return attributes;
}

/**
 返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载
 @param parameter
 @return result
 */
//- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
//{
//    return nil;
//}
@end

ShelfView.h

#import <UIKit/UIKit.h>

@interface ShelfView : UICollectionReusableView

+ (NSString *)kind;

@end

ShelfView.m

#import "ShelfView.h"
#import <QuartzCore/QuartzCore.h>

const NSString *kShelfViewKind = @"ShelfView";

@implementation ShelfView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bookGridShelf.png"]]];
//        self.layer.shadowOpacity = 0.5;
//        self.layer.shadowOffset = CGSizeMake(0,5);
    }
    return self;
}

- (void)layoutSubviews
{
//    CGRect shadowBounds = CGRectMake(0, -5, self.bounds.size.width, self.bounds.size.height + 5);
//    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowBounds].CGPath;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

+ (NSString *)kind
{
    return (NSString *)kShelfViewKind;
}

@end

GridLayoutAttributes.h

#import <UIKit/UIKit.h>

@interface GridLayoutAttributes : UICollectionViewLayoutAttributes

@end

GridLayoutAttributes.m

#import "GridLayoutAttributes.h"

@implementation GridLayoutAttributes

@end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值