定制通用的标签选择器
定制通用的标签选择器
效果
源码
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