寫在前面的話:
最近產(chǎn)品要求做個(gè)需求,比較奇葩挣轨,選擇時(shí)間的军熏,本來原生的UIDatePickerView很好用,可是產(chǎn)品非要搞成這個(gè)樣子:
這樣一來就只能自定義了,誰叫程序員不擅長拒絕呢卷扮,以下是實(shí)現(xiàn)這個(gè)頁面的一些記錄荡澎,需要的話文章末尾也有源碼,歡迎收藏晤锹、star...
版權(quán)聲明:本文為博主原創(chuàng)文章摩幔,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:http://www.reibang.com/p/6730c1b6e81b
概述
這個(gè)功能是選擇日期的鞭铆,上部顯示的是一個(gè)刻度尺或衡,可以左右拖動(dòng),可選擇全年的日期,選中后下方的按鈕會(huì)顯示出選中的月份和年封断;點(diǎn)擊下方的按鈕后會(huì)彈出時(shí)間選擇器斯辰,可選擇任意時(shí)間,選中后也會(huì)反顯對(duì)應(yīng)的月份和年坡疼,上部的刻度尺也會(huì)滾動(dòng)到對(duì)應(yīng)的位置彬呻,預(yù)覽如下:
試著使用UIPickerView實(shí)現(xiàn)
剛拿到這個(gè)任務(wù)的時(shí)候,也是百度柄瑰、Github一頓找闸氮,沒找到有類似的控件(這么說來產(chǎn)品還比較優(yōu)秀),沒辦法只能自己手敲了狱意。這個(gè)刻度尺的實(shí)現(xiàn)是個(gè)難點(diǎn)湖苞,有點(diǎn)像UIPickerView拯欧,但是又是橫過來的详囤。那就先寫好豎著的刻度尺然后旋轉(zhuǎn)一下,開干镐作,實(shí)現(xiàn)以后發(fā)現(xiàn)旋轉(zhuǎn)頁面會(huì)變形藏姐,刻度尺也是彎著的,這個(gè)思路也就終結(jié)了该贾。
使用UICollectionView實(shí)現(xiàn)
那就使用UICollectionView實(shí)現(xiàn)吧羔杨,自定義Cell,增加Label杨蛋,刻度尺用貝塞爾曲線畫出來兜材,這些都比較容易實(shí)現(xiàn),就不貼代碼了逞力。
個(gè)人認(rèn)為實(shí)現(xiàn)這個(gè)刻度尺的關(guān)鍵點(diǎn):
1.獲取一年12個(gè)月的數(shù)據(jù):
+ (NSMutableArray *)getAllDaysWith:(NSDate *)date {
NSString *year = [self getYearWith:date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
//設(shè)置轉(zhuǎn)換后的目標(biāo)日期時(shí)區(qū)
NSTimeZone *toTimeZone = [NSTimeZone defaultTimeZone];
//轉(zhuǎn)換后源日期與世界標(biāo)準(zhǔn)時(shí)間的偏移量
NSInteger toGMTOffset = [toTimeZone secondsFromGMTForDate:[NSDate date]];
[dateFormatter setTimeZone: [NSTimeZone timeZoneForSecondsFromGMT:toGMTOffset]];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:12];
for (int i = 1; i < 13; i++) {
NSString *firstDay = [year stringByAppendingFormat:@"-%02d-01", i];
NSDate *date = [dateFormatter dateFromString:firstDay];
NSInteger days = [self getMonthNumberDaysWithDate:date];
NSMutableArray *daysArray = [NSMutableArray arrayWithCapacity:days];
for (int j = 1; j <= days; j++) {
[daysArray addObject:[NSString stringWithFormat:@"%02d", j]];
}
array[i-1] = daysArray;
}
return array;
}
該方法返回二維數(shù)組曙寡,可直接顯示每個(gè)月的每一天。
2.滾動(dòng)到1月1號(hào)和12月31號(hào)的時(shí)候如何能夠無縫的顯示寇荧?
想著和無限輪播圖一樣實(shí)現(xiàn)举庶,但這個(gè)cell又不是整屏顯示的,根本沒辦法實(shí)現(xiàn)揩抡。
后臺(tái)也是在網(wǎng)上受到的啟發(fā)户侥,直接更改數(shù)據(jù)源,我只顯示一年12個(gè)月的時(shí)間峦嗤,因此我直接把數(shù)據(jù)改為36個(gè)月蕊唐,我顯示的時(shí)候只顯示中間12個(gè)月的時(shí)間,這樣就能夠順滑的顯示烁设。
^^正常應(yīng)該沒人會(huì)手動(dòng)滑365個(gè)cell看我的邊界吧 ^^
如果有大神知道更好的方法替梨,希望能給我留言,萬分感謝!0姨妗亚侠!
- (void)setSelectedIndexPath:(NSIndexPath *)selectedIndexPath {
/// 選中數(shù)據(jù)后放到中間組顯示
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:selectedIndexPath.row inSection:selectedIndexPath.section+12];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:(UICollectionViewScrollPositionCenteredHorizontally) animated:YES];
}
- (void)setDataArray:(NSArray *)dataArray {
/// 創(chuàng)建三組數(shù)據(jù),避免邊界值不能選擇的問題
NSMutableArray *mutableArray = dataArray.mutableCopy;
[mutableArray addObjectsFromArray:dataArray];
[mutableArray addObjectsFromArray:dataArray];
_dataArray = mutableArray.copy;
[self.collectionView reloadData];
}
模糊&漸變
這也是比較常規(guī)代碼,就不贅述了俗扇,直接上代碼:
/// 增加模糊效果
CGFloat space = 10;
CGFloat widthRatio = 0.15;
CGFloat viewHeight = self.frame.size.height - space;
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:(UIBlurEffectStyleExtraLight)];
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
effectView.alpha = 0.5;
effectView.frame = CGRectMake(self.collectionView.frame.origin.x, self.collectionView.frame.origin.y + space, self.frame.size.width * widthRatio, viewHeight);
[self addSubview:effectView];
/// 增加漸變效果
UIColor *color = [UIColor lightGrayColor];
CAGradientLayer *viewALayer = [CAGradientLayer layer];
viewALayer.frame = effectView1.bounds;
viewALayer.colors = [NSArray arrayWithObjects:
(id)[UIColor whiteColor].CGColor,
(id)color.CGColor, nil];
viewALayer.startPoint = CGPointMake(0, 0);
viewALayer.endPoint = CGPointMake(1, 0);
[effectView1.layer addSublayer: viewALayer];
tips: 使用Xcode 11創(chuàng)建的項(xiàng)目硝烂,如果使用低版本的Xcode運(yùn)行可能會(huì)報(bào)錯(cuò)。
實(shí)現(xiàn)的過程比較曲折和匆忙铜幽,如有bug請(qǐng)留言反饋滞谢,謝謝。