- #import "XKCollectionView.h"
-
- ///四周边距
- const static CGFloat _margin_left = 5;
- const static CGFloat _margin_right = 5;
- const static CGFloat _margin_top = 0;
- const static CGFloat _margin_bottom = 2;
- const static CGFloat _margin_space = 15;
- const static CGFloat _line_width = 30.0;
- const static CGFloat _line_height = 3.0;
- @interface XKCollectionView ()<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
- ///临时数据
- @property (nonatomic,strong) NSArray<NSString *> *titleArray;
- ///每个item的宽度
- @property (nonatomic,strong) NSMutableArray *widthsArray;
- ///底部线条
- @property (nonatomic,strong) UIView *lineView;
- ///选中的item索引
- @property (nonatomic,assign) NSInteger selectIndex;
- ///选中的item string
- @property (nonatomic,strong) NSString *selectString;
- ////计算出来的总宽度,用于设置 UICollectionView.contentSize.width
- @property (nonatomic,assign) CGFloat totalContentWidth;
- @end
- @implementation XKCollectionView
- - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout{
- self = [super initWithFrame:frame collectionViewLayout:layout];
- if (self) {
- [self setup];
- }
- return self;
- }
- - (void)setup{
- _selectIndex = 0;
- self.widthsArray = [NSMutableArray array];
- [self addSubview:self.lineView];
- self.backgroundColor = [UIColor whiteColor];
- self.showsHorizontalScrollIndicator = NO;
- self.delegate = self;
- self.dataSource = self;
- [self registerClass:[XKCollectionViewCell class] forCellWithReuseIdentifier:@"XKCollectionViewCell"];
-
- _titleArray = @[@"一级建造师",@"二级建造师",@"造价工程师",@"咨询工程师",@"注册安全工程师",@"监理工程师",@"注册电气工程师",@"环境影响评价工程师",@"注册城乡规划师",@"注册消防工程师"];
- [self storeSegmentedWidth];
- [self reloadData];
- CGRect lineRext = [self measureLineFrame];
- self.lineView.frame = lineRext;
- ///设置偏移量
- [self setContentOffset:CGPointMake([self measureContentOffsetX], 0)];
- }
- - (void)updateSelectSeg{
- [self storeSegmentedWidth];
- [self reloadData];
- [UIView animateWithDuration:0.3 animations:^{
- CGRect lineRext = [self measureLineFrame];
- self.lineView.frame = lineRext;
- }];
-
- [self setContentOffset:CGPointMake([self measureContentOffsetX], 0) animated:YES];
- }
- #pragma mark ========== 储存计算好的item宽度 ==========
- ///每次切换时更新
- - (void)storeSegmentedWidth{
- _selectIndex = 0;
- _totalContentWidth = 0;
- [self.widthsArray removeAllObjects];
-
- if (_selectString) {
- for (int i = 0; i < _titleArray.count; i ++) {
- NSString *title = _titleArray[i];
- if ([title isEqualToString:_selectString]) {
- _selectIndex = i;
- break;
- }
- }
- }
-
-
- for (int i = 0; i < _titleArray.count; i ++) {
-
- CGSize size = [self measureTitleIndex:i];
- NSNumber *value = [NSNumber numberWithFloat:size.width];
- [self.widthsArray addObject:value];
-
- _totalContentWidth = _totalContentWidth + size.width;
- if (i < _titleArray.count - 1) {
- _totalContentWidth = _totalContentWidth + _margin_space;
- }
- }
- _totalContentWidth = _totalContentWidth + _margin_left + _margin_right;
-
- }
- - (CGSize)measureTitleIndex:(NSUInteger)index {
- if (index >= _titleArray.count) {
- return CGSizeZero;
- }
-
- id title = _titleArray[index];
- CGSize size = CGSizeZero;
- BOOL selected = (index == _selectIndex);
- NSDictionary *titleAttrs = selected ? [self resultingSelectedTitleTextAttributes] : [self resultingTitleTextAttributes];
- size = [(NSString *)title sizeWithAttributes:titleAttrs];
- UIFont *font = titleAttrs[@"NSFont"];
- size = CGSizeMake(ceil(size.width), ceil(size.height - font.descender));
- CGSize resault = CGRectIntegral((CGRect){CGPointZero, size}).size;
- return resault;
- }
- - (NSDictionary *)resultingSelectedTitleTextAttributes {
- NSDictionary *resultingAttrs = @{NSForegroundColorAttributeName : [UIColor blackColor] ,NSFontAttributeName:[UIFont fontWithName:@"Helvetica-Bold" size:18.0]};
- return resultingAttrs;
- }
- - (NSDictionary *)resultingTitleTextAttributes {
- NSDictionary *resultingAttrs = @{NSForegroundColorAttributeName : [UIColor lightGrayColor],NSFontAttributeName:[UIFont systemFontOfSize:14.0]};
- return resultingAttrs;
- }
- #pragma mark ========== 计算下划线位置 ==========
- - (CGRect)measureLineFrame{
- CGRect lineRect = CGRectZero;
- CGFloat lineRectX = 0;
- for (int i = 0; i < _selectIndex; i ++) {
- NSNumber *number = self.widthsArray[i];
- lineRectX = lineRectX + [number floatValue] + _margin_space;
- }
- CGFloat widthSelect = [self.widthsArray[_selectIndex] floatValue];
- CGFloat lastLocation = widthSelect >= _line_width ? (widthSelect - _line_width)/2 : (_line_width - widthSelect)/2;
- lineRectX = lineRectX + _margin_left + lastLocation;
-
- lineRect = CGRectMake(lineRectX, self.bounds.size.height - _line_height - 2, _line_width, _line_height);
- return lineRect;
- }
- #pragma mark ========== 计算偏移量 ==========
- - (CGFloat)measureContentOffsetX{
- CGFloat selfWidth = self.bounds.size.width;
-
- ///先计算点击的item中心点
- CGFloat selectedCenterX = 0;
- for (int i = 0; i < _selectIndex; i ++) {
- NSNumber *number = self.widthsArray[i];
- selectedCenterX = selectedCenterX + [number floatValue] + _margin_space;
- }
- CGFloat widthSelect = [self.widthsArray[_selectIndex] floatValue];
- selectedCenterX = selectedCenterX + widthSelect/2;
-
- if (_totalContentWidth <= selfWidth) {///充满内部不做偏移
- return 0;
- }
-
- if (selectedCenterX <= selfWidth/2) {
- return 0;
- }
- else if (selectedCenterX >= _totalContentWidth - selfWidth/2){
- return _totalContentWidth - selfWidth;
- }
- else{
- return selectedCenterX - selfWidth/2;
- }
- }
- #pragma mark ========== 代理 ==========
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
- return _titleArray.count;
- }
- - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
- return _margin_space;
- }
- - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
- return UIEdgeInsetsMake(_margin_top, _margin_left, _margin_bottom, _margin_right);
- }
- //item大小
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
- NSNumber *number = self.widthsArray[indexPath.row];
- return CGSizeMake([number floatValue],30);
- }
- - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
- XKCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"XKCollectionViewCell" forIndexPath:indexPath];
- NSString *title = _titleArray[indexPath.row];
- cell.title = title;
- if (indexPath.row == _selectIndex) {
- cell.isSelectd = YES;
- }
- else{
- cell.isSelectd = NO;
- }
- return cell;
- }
- - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
- _selectString = _titleArray[indexPath.row];
- [self updateSelectSeg];
- }
- #pragma mark ========== 变量 ==========
-
- - (UIView *)lineView{
- if(!_lineView){
- _lineView = [[UIView alloc]init];
- _lineView.backgroundColor = [UIColor purpleColor];
- _lineView.layer.masksToBounds = YES;
- _lineView.layer.cornerRadius = _line_height/2;
- }
- return _lineView;
- }
- @end