https://github.com/YouXianMing

定制通用的标签选择器

定制通用的标签选择器

 

效果

 

源码

https://github.com/YouXianMing/UI-Component-Collection 中的 CollectionGridView

//
//  CollectionGridView.h
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "CollectionGridCellDataAdapter.h"
#import "CustomCollectionGridViewCell.h"
@class CollectionGridView;
@class CollectionGridViewCellClassType;

#pragma mark - CollectionGridView Class

@protocol CollectionGridViewDelegate <NSObject>

@optional

/**
 *  CollectionGridView did selected event.
 *
 *  @param collectionGridView CollectionGridView's object.
 *  @param cell               CustomCollectionGridViewCell type's cell.
 */
- (void)collectionGridView:(CollectionGridView *)collectionGridView didSelectedCell:(CustomCollectionGridViewCell *)cell;

@end

@interface CollectionGridView : UIView

/**
 *  CollectionGridView's delegate.
 */
@property (nonatomic, weak) id <CollectionGridViewDelegate> delegate;

/**
 *  content edgeInsets, default is UIEdgeInsetsMake(5, 5, 5, 5).
 */
@property (nonatomic) UIEdgeInsets contentEdgeInsets;

/**
 *  Horizontal item's gap, default is 5.f.
 */
@property (nonatomic) CGFloat horizontalGap;

/**
 *  Vertical item's gap, default is 5.f.
 */
@property (nonatomic) CGFloat verticalGap;

/**
 *  Item's height, default is 20.f.
 */
@property (nonatomic) CGFloat gridHeight;

/**
 *  The cell's count at the horizontal direction, default is 3.
 */
@property (nonatomic) NSUInteger horizontalCellCount;

/**
 *  Register the cells.
 */
@property (nonatomic, strong) NSArray <CollectionGridViewCellClassType *> *registerCells;

/**
 *  The cells data adapter.
 */
@property (nonatomic, strong) NSArray <CollectionGridCellDataAdapter *> *adapters;

/**
 *  To make the config effective.
 */
- (void)makeTheConfigEffective;

/**
 *  Reset the view's size.
 */
- (void)resetSize;

/**
 *  Get the cell's size.
 */
@property (nonatomic, readonly) CGSize cellSize;

/**
 *  Get the CollectionView's content size.
 */
@property (nonatomic, readonly) CGSize contentSize;

/**
 *  Reloads just the items at the specified index paths.
 *
 *  @param indexPaths An array of NSIndexPath objects identifying the items you want to update.
 */
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;

/**
 *  Reload data.
 */
- (void)reloadData;

@end

#pragma mark - CollectionGridViewCellClassType Class

@interface CollectionGridViewCellClassType : NSObject

@property (nonatomic)         Class      className;
@property (nonatomic, strong) NSString  *reuseIdentifier;

@end

NS_INLINE CollectionGridViewCellClassType *gridViewCellClassType(Class className, NSString  *reuseIdentifier) {
    
    CollectionGridViewCellClassType *type = [CollectionGridViewCellClassType new];
    type.className                        = className;
    type.reuseIdentifier                  = reuseIdentifier;
    
    return type;
}
//
//  CollectionGridView.m
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "CollectionGridView.h"

@implementation CollectionGridViewCellClassType

@end

@interface CollectionGridView () <UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView            *collectionView;
@property (nonatomic, strong) UICollectionViewFlowLayout  *flowLayout;

@property (nonatomic) CGSize cellSize;
@property (nonatomic) CGSize contentSize;

@end

@implementation CollectionGridView

#pragma mark - Init

- (void)layoutSubviews {
    
    [super layoutSubviews];
    _collectionView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}

- (instancetype)initWithFrame:(CGRect)frame {
    
    if (self = [super initWithFrame:frame]) {
        
        self.contentEdgeInsets   = UIEdgeInsetsMake(5, 5, 5, 5);
        self.horizontalGap       = 5.f;
        self.verticalGap         = 5.f;
        self.gridHeight          = 20.f;
        self.horizontalCellCount = 3;
        
        // Init UICollectionViewFlowLayout.
        self.flowLayout                         = [[UICollectionViewFlowLayout alloc] init];
        self.flowLayout.minimumInteritemSpacing = 0;
        
        // Init UICollectionView.
        self.collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.flowLayout];
        self.collectionView.showsHorizontalScrollIndicator = NO;
        self.collectionView.showsVerticalScrollIndicator   = NO;
        self.collectionView.backgroundColor                = [UIColor clearColor];
        self.collectionView.delegate                       = self;
        self.collectionView.dataSource                     = self;
        [self addSubview:self.collectionView];        
    }
    
    return self;
}

- (void)makeTheConfigEffective {

    CGFloat width     = self.frame.size.width;
    CGFloat cellWidth = (width - self.contentEdgeInsets.left -
                         self.contentEdgeInsets.right -
                         _horizontalGap * (_horizontalCellCount - 1)) / (CGFloat)_horizontalCellCount;
    
    self.collectionView.contentInset        = self.contentEdgeInsets;
    self.flowLayout.minimumLineSpacing      = self.verticalGap;
    self.flowLayout.minimumInteritemSpacing = self.horizontalGap;
    self.flowLayout.itemSize                = CGSizeMake(cellWidth, self.gridHeight);
    
    self.cellSize = self.flowLayout.itemSize;
}

#pragma mark - Reload data.

- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {

    [self.collectionView reloadItemsAtIndexPaths:indexPaths];
}

- (void)reloadData {

    [self.collectionView reloadData];
}

#pragma mark - UICollectionView's delegate & data source.

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    
    return _adapters.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    CollectionGridCellDataAdapter *adapter = _adapters[indexPath.row];
    CustomCollectionGridViewCell  *cell    = [collectionView dequeueReusableCellWithReuseIdentifier:adapter.cellReuseIdentifier
                                                                                       forIndexPath:indexPath];
    cell.dataAdapter        = adapter;
    cell.data               = adapter.data;
    cell.indexPath          = indexPath;
    cell.collectionView     = collectionView;
    cell.collectionGridView = self;
    [cell loadContent];
    
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    
    CustomCollectionGridViewCell *cell = (CustomCollectionGridViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
    [cell selectedEvent];
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(collectionGridView:didSelectedCell:)]) {
        
        [self.delegate collectionGridView:self didSelectedCell:cell];
    }
}

#pragma mark - Setter & Getter

- (void)setRegisterCells:(NSArray <CollectionGridViewCellClassType *> *)registerCells {
    
    _registerCells = registerCells;
    
    for (CollectionGridViewCellClassType *type in registerCells) {
        
        [self.collectionView registerClass:type.className forCellWithReuseIdentifier:type.reuseIdentifier];
    }
}

- (CGSize)contentSize {

    CGSize size = [_flowLayout collectionViewContentSize];
    
    size.width  += self.contentEdgeInsets.left + self.contentEdgeInsets.right;
    size.height += self.contentEdgeInsets.top  + self.contentEdgeInsets.bottom;
    
    return size;
}

- (void)resetSize {

    CGRect newFrame = self.frame;
    newFrame.size   = [self contentSize];
    self.frame      = newFrame;
}

@end
//
//  CustomCollectionGridViewCell.h
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "CollectionGridCellDataAdapter.h"
@class CollectionGridView;

@interface CustomCollectionGridViewCell : UICollectionViewCell

@property (nonatomic, weak) id                              data;
@property (nonatomic, weak) CollectionGridCellDataAdapter  *dataAdapter;
@property (nonatomic, weak) UICollectionView               *collectionView;
@property (nonatomic, weak) NSIndexPath                    *indexPath;
@property (nonatomic, weak) CollectionGridView             *collectionGridView;

#pragma mark - Method you should overwrite.

/**
 *  Setup cell, override by subclass.
 */
- (void)setupCell;

/**
 *  Build subview, override by subclass.
 */
- (void)buildSubview;

/**
 *  Load content, override by subclass.
 */
- (void)loadContent;

/**
 *  Selected event, override by subclass.
 */
- (void)selectedEvent;

#pragma mark - Constructor.

+ (CollectionGridCellDataAdapter *)dataAdapterWithCellReuseIdentifier:(NSString *)reuseIdentifier
                                                                 data:(id)data
                                                                 type:(NSInteger)type;

@end
//
//  CustomCollectionGridViewCell.m
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "CustomCollectionGridViewCell.h"

@implementation CustomCollectionGridViewCell

- (instancetype)initWithFrame:(CGRect)frame {
    
    if (self = [super initWithFrame:frame]) {
        
        [self setupCell];
        
        [self buildSubview];
    }
    
    return self;
}

- (void)setupCell {
    
}

- (void)buildSubview {
    
}

- (void)loadContent {
    
}

- (void)selectedEvent {
    
}

+ (CollectionGridCellDataAdapter *)dataAdapterWithCellReuseIdentifier:(NSString *)reuseIdentifier data:(id)data type:(NSInteger)type {

    NSString *identifierString = nil;
    reuseIdentifier.length <= 0 ? (identifierString = NSStringFromClass([self class])) : (identifierString = reuseIdentifier);
    
    return [CollectionGridCellDataAdapter collectionGridCellDataAdapterWithCellReuseIdentifier:identifierString data:data cellType:type];
}

@end
//
//  CollectionGridCellDataAdapter.h
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface CollectionGridCellDataAdapter : NSObject

@property (nonatomic, strong) id             data;
@property (nonatomic, strong) NSString      *cellReuseIdentifier;
@property (nonatomic, weak)   NSIndexPath   *indexPath;
@property (nonatomic)         NSInteger      cellType;

+ (instancetype)collectionGridCellDataAdapterWithCellReuseIdentifier:(NSString *)cellReuseIdentifier
                                                                data:(id)data
                                                            cellType:(NSInteger)cellType;

@end

NS_INLINE CollectionGridCellDataAdapter *collectionGridCellDataAdapter(NSString *cellReuseIdentifier, id data, NSInteger type) {

    return [CollectionGridCellDataAdapter collectionGridCellDataAdapterWithCellReuseIdentifier:cellReuseIdentifier
                                                                                          data:data cellType:type];
}
//
//  CollectionGridCellDataAdapter.m
//  CollectionView
//
//  Created by YouXianMing on 16/7/14.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "CollectionGridCellDataAdapter.h"

@implementation CollectionGridCellDataAdapter

+ (instancetype)collectionGridCellDataAdapterWithCellReuseIdentifier:(NSString *)cellReuseIdentifier
                                                                data:(id)data
                                                            cellType:(NSInteger)cellType {

    CollectionGridCellDataAdapter *adapter = [[self class] new];
    adapter.cellReuseIdentifier            = cellReuseIdentifier;
    adapter.data                           = data;
    adapter.cellType                       = cellType;
    
    return adapter;
}

@end

 

posted @ 2016-07-17 14:51  YouXianMing  阅读(635)  评论(0编辑  收藏  举报