系统自带的分段选择就是 UISegmentedControl ,也有一些大佬自定义的 Segmented ,比如Git上的 HMSegmentedControl ,我以前最初的项目中,也有用到过,如果自己写,或者想自定义一些UI,该从哪里出发,其实在用过 HMSegmentedControl 之后,大致就有思路了,如果想简单的实现下,可以利用 UICollectionView 来实现,下面是我利用 UICollectionView 写的一个简单的小栗子,效果图
设计思路
首先利用 UICollectionView 处理每个item的大小,确切的说是宽度,那么就要每次选中一个item后,重新计算所有的item的宽度,同时计算 UICollectionView 的 contentSize.width;
计算每个item宽度分为两种情况,一种是选中的字体的显示,一种是未选中的字体显示,比如字体大小,颜色等,然后根据字体大小字符串长度,计算出字体需要展示的宽度,并计算对应的item宽度,最后把每个item的宽度保存起来,用于在 UICollectionView 代理方法中做处理;
计算 contentSize.width 由上图可知,是由两边的间距,item之间的间距和每个item的总和,目的是利用 contentSize.width 计算下划线的位置;
具体实现
#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];