年前的某天棚潦,公司的UI拿了張?jiān)O(shè)計(jì)圖讓我看下能否實(shí)現(xiàn)令漂,隨意一瞥發(fā)現(xiàn)只是個(gè)PickerView,心想著用UIPickerView封裝一下還不是so easy的事情丸边,然而接下去了解了需求后才發(fā)現(xiàn)沒(méi)那么簡(jiǎn)單......
需要實(shí)現(xiàn)的效果
具體需求如下:
- 需要能自定義選中顏色及未選中顏色叠必,且跟隨滾動(dòng)實(shí)時(shí)變化;
- 需要能自定義選中指示器妹窖;
- 需要滾動(dòng)效果是平面滾動(dòng)纬朝;
根據(jù)上面的需求,翻看了下UIPickerView的接口并寫代碼測(cè)試了下后發(fā)現(xiàn)情況不容樂(lè)觀:
- UIPickerView默認(rèn)不支持選中顏色設(shè)置骄呼,可通過(guò)自定義view實(shí)現(xiàn)共苛,但是無(wú)法跟隨滾動(dòng)實(shí)時(shí)變化判没;
- UIPickerView原生不支持設(shè)置選中指示器樣式;
- UIPickerView默認(rèn)滾動(dòng)效果為類曲面滾動(dòng)隅茎,且不支持設(shè)置澄峰;
到現(xiàn)在已經(jīng)基本確定UIPickerView的方案已經(jīng)被斃了,不過(guò)沒(méi)關(guān)系辟犀,原生沒(méi)法實(shí)現(xiàn)那么就自己實(shí)現(xiàn)一個(gè)俏竞,于是 STDPickerView 就在這種情況下誕生了:
STDPickerView 是什么
STDPickerView 是基于 UICollectionView 封裝的選擇控件,兼容UIPickerView大部分接口堂竟,并增加了多個(gè)定制化接口魂毁,可實(shí)現(xiàn)更多的效果!STDPickerView 效果圖如下:
默認(rèn)樣式
分割選中指示器
垂直分割線
自定義view
STDPickerView 怎么使用
- 初始化
STDPickerView *pickerView = [[STDPickerView alloc] init];
pickerView.dataSource = self;
pickerView.delegate = self;
/*
STDPickerViewSelectionIndicatorStyleNone:無(wú)選中指示器
STDPickerViewSelectionIndicatorStyleDefault:默認(rèn)選中指示器
STDPickerViewSelectionIndicatorStyleDivision: 分段選中指示器
STDPickerViewSelectionIndicatorStyleCustom:自定義選中指示器出嘹,需實(shí)現(xiàn) selectionIndicatorViewInPickerView: 代理方法
*/
pickerView.selectionIndicatorStyle = STDPickerViewSelectionIndicatorStyleDefault;
/*
默認(rèn)情況下席楚,如果同時(shí)實(shí)現(xiàn)了titleForRow以及viewForRow數(shù)據(jù)源方法,
則會(huì)優(yōu)先使用viewForRow方法返回自定義view税稼,
此時(shí)可設(shè)置 forceItemTypeText = YES 來(lái)指定使用titleForRow方法
*/
pickerView.forceItemTypeText = YES;
//是否顯示垂直分割線
pickerView.showVerticalDivisionLine = YES;
//設(shè)置pickerView四周的間距
pickerView.edgeInsets = UIEdgeInsetsMake(0, 20, 0, 20);
//設(shè)置component之間的間距
pickerView.spacingOfComponents = 30;
//僅在文本模式下有效
pickerView.textColor = kLightTextColor;
pickerView.selectedTextColor = kGlobalColor;
pickerView.font = [UIFont systemFontOfSize:16];
...
[self.view addSubview:pickerView];
- 通用數(shù)據(jù)源及代理方法
#pragma mark - STDPickerViewDataSource
//返回component數(shù)目
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
//返回row數(shù)目
- (NSInteger)pickerView:(STDPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return self.items.count;
}
#pragma mark - STDPickerViewDelegate
//返回條目高度
- (CGFloat)pickerView:(STDPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 60;
}
//選中了某個(gè)條目
- (void)pickerView:(STDPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(@"pickerView - didSelectRow %zd inComponent %zd", row, component);
}
//若selectionIndicatorStyle = STDPickerViewSelectionIndicatorStyleCustom烦秩,則需實(shí)現(xiàn)以下方法
- (UIView *)selectionIndicatorViewInPickerView:(STDPickerView *)pickerView
{
UIView *view = [[UIView alloc] init];
view.backgroundColor = kGlobalColorWithAlpha(0.3);
view.layer.cornerRadius = 5;
view.layer.masksToBounds = YES;
return view;
}
...
- 默認(rèn)選中樣式
#pragma mark - STDPickerViewDataSource
// 返回item的標(biāo)題
(注:若同時(shí)實(shí)現(xiàn)了 pickerView: viewForRow:forComponent:reusingView: 優(yōu)先采用后者,此時(shí)可通過(guò)設(shè)置 forceItemTypeText = YES 來(lái)強(qiáng)制使用本方法)
- (NSString *)pickerView:(STDPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return self.items[row];
}
- 自定義選中樣式
#pragma mark - STDPickerViewDataSource
// 返回item的自定義view娶聘,優(yōu)先級(jí)較高
(注:若同時(shí)實(shí)現(xiàn)了 pickerView: titleForRow:forComponent: 且 forceItemTypeText = YES 則本方法無(wú)效)
- (UIView *)pickerView:(STDPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *label = (UILabel *)view;
if (!label) {
label = [[UILabel alloc] init];
label.textAlignment = NSTextAlignmentCenter;
}
label.textColor = kLightTextColor;
label.transform = CGAffineTransformIdentity;
label.text = self.items[row];
return label;
}
#pragma mark - STDPickerViewDelegate
//可在此方法及willDeselectRow中實(shí)現(xiàn)自定義的切換效果
- (void)pickerView:(STDPickerView *)pickerView willSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
UILabel *label = (UILabel *)[pickerView viewForRow:row forComponent:component];
[UIView animateWithDuration:0.25 animations:^{
label.transform = CGAffineTransformMakeScale(1.5, 1.5);
}];
label.textColor = kGlobalColor;
}
- (void)pickerView:(STDPickerView *)pickerView willDeselectRow:(NSInteger)row inComponent:(NSInteger)component
{
UILabel *label = (UILabel *)[pickerView viewForRow:row forComponent:component];
[UIView animateWithDuration:0.25 animations:^{
label.transform = CGAffineTransformIdentity;
}];
label.textColor = kLightTextColor;
}
目前 STDPickerView 已經(jīng)開源到GitHub上并支持CocoaPods集成闻镶,歡迎大家下載與star!