iOS 横向无限滑动选择日期控件
2017-05-23 本文已影响2025人
JasonEVA
最近做了一个横向滑动选择日期的控件,记录一下。
效果如下:
主要就是用于选择日期来做一些刷新数据UI之类的操作
具体实现
拿到需求的时候开始构思实现的方式,一开始是想使用UIScrollView来实现,但考虑到可以按周滑动(就是按页翻,一翻翻一个星期),决定用UICollectionView实现会更加方便一点。
实现控件决定后,还有数据源问题,怎么样获取数据源呢?
1.首先要确定一个开始时间点(startDate),一般就选当前时间为开始时间,将开始时间插入数据源dataList
2.获取开始时间(startDate)是周几(week,确定默认一次加载的周数offsetWeeks
3.在数据源dataList前面循环插入开始时间(startDate)前的(offsetWeeks * 7 + week - 1)个日期
4.在数据源dataList后面循环插入开始时间(startDate)后的(offsetWeeks * 7 + 7 - week)个日期
[_dateDataList addObject:self.selectedDate];
NSInteger week = [self.selectedDate weekday];
// 插入开始日期前的数组
for (int i = 1; i <= OFFSETDAYS + week - 1; i++) {
[_dateDataList insertObject:[self.selectedDate dateBySubtractingDays:i] atIndex:0];
}
// 插入开始日期后的数组
for (int i = 1; i <= OFFSETDAYS + 7 - week; i++) {
[_dateDataList addObject:[self.selectedDate dateByAddingDays:i]];
}
如何实现无限滑动
无限滑动其实只是视觉上的错觉,UICollectionView的滑动范围是由数据源决定的,但是一次设置无限数据源显然是不现实的。所以我选择的实现方式是在滑动到最前或最后的时候增加数据源,并且滑动到适当位置,达到无限滑动的效果。
实现UIScrollView回调方法:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
CGFloat contentOffsetX = self.dateCollectView.contentOffset.x;
if (scrollView == self.dateCollectView) {
// 无限向左拉
if (contentOffsetX > self.contentWidth - ScreenWidth)
{
[self addNextBatchData];
}
// 无限向右拉
else if (contentOffsetX < 0)
{
[self addLastBatchData];
}
}
}
在数据源后插入新数据
// collectionView下一批
- (void)addNextBatchData
{
// 插入开始日期后的数组
NSDate *tempDate = self.dateDataList.lastObject;
for (int i = 1; i <= OFFSETDAYS; i++) {
[_dateDataList addObject:[tempDate dateByAddingDays:i]];
}
self.contentWidth = self.dateDataList.count * WEEKWIDTH;
[self performSelector:@selector(scrollNext) withObject:nil afterDelay:0.00001];
[self.dateCollectView reloadData];
}
在数据源前插入新的数据
// collectionView上一批
- (void)addLastBatchData
{
// 插入开始日期前的数组
NSDate *tempDate = self.dateDataList.firstObject;
for (int i = 1; i <= OFFSETDAYS; i++) {
[_dateDataList insertObject:[tempDate dateBySubtractingDays:i] atIndex:0];
}
self.contentWidth = self.dateDataList.count * WEEKWIDTH;
[self performSelector:@selector(scrollLast) withObject:nil afterDelay:0.00001];
[self.dateCollectView reloadData];
}