日历时间块布局实现

需求:实现一个日历显示页面如下:

左侧刻度从早上9点开始,到晚上9点结束。以分钟为单位。动态给时间块定位并分配空间。

测试数据一:

var events = [
   {start: 30, end: 150},
   {start: 540, end: 600},
   {start: 560, end: 620}, 
   {start: 610, end: 670}
];
日历时间块布局实现_第1张图片
测试数据一

测试数据二:

var events = [
   {start: 30, end: 150}, 
   {start: 540, end: 600}, 
   {start: 550, end: 620}, 
   {start: 560, end: 650}, 
   {start: 630, end: 690},
];
日历时间块布局实现_第2张图片
测试数据二

测试数据三:

var events = [
   {start:30,end:670},
   {start:100,end:180},
   {start:180,end:200}, 
   {start:210,end:480}, 
   {start:220,end:490},
   {start:250,end:500}, 
   {start:280,end:510}, 
   {start:540,end:600}, 
   {start:550,end:620}, 
   {start:560,end:650}, 
   {start:630,end:690}, 
   {start:640,end:700},
];
日历时间块布局实现_第3张图片
测试数据三

思路:

(1)每一个待办事项都是一个区间,而我们首先要确定的是事情最多的那一分钟处于多少个区间内,以此来计算最小的时间块宽度。
(2)确定了宽度最小的时间块以后,剩下的时间块平分剩下的宽度。
(3)首先想到的是遍历从9:00--21:00的每一分钟内有几个待办事项,需要遍历12*60=720次,显然这种做法太蠢了,我们只需要遍历每个待办事项开始时间点就行了。

日历时间块布局实现_第4张图片
image.png

步骤

(1)我们将每一个时间块看成一个区间对象region,用一个数组regionArr读入存放它们。
(2)再建立一个数组beginArr,存放每一个时间块开始的时间点,去掉重复的元素
(3)遍历beginArr里的元素(开始时间点),得出包含该时间点的所有时间块,放入数组,按照开始时间排序。最后将所有数组放入一个大数组crossRegionArr,按照数组内的元素个数排序。
(4)遍历crossRegionArr,取出数组crossRegionArr[0],画出crossRegionArr[0]内的所有时间块。时间块宽度均为屏幕宽度除以crossRegionArr[0]的count,添加到屏幕上,标记为已添加。取出数组crossRegionArr[1],遍历crossRegionArr[1]的元素。如果crossRegionArr[1]中包含已添加到屏幕上的时间块,那么应该去掉该时间块的所占的宽度。剩余的未添加的时间块平分宽度。

以测试数据一为例

日历时间块布局实现_第5张图片
image.png

得到排序后的大数组以后,开始绘制时间块。

(1)首先画[540,600),[560,620),画出两个绿色的时间块
(2)画[560,620),[610,670)[560,620)已在屏幕上。减去[560,620)的宽度,[610,670)平分剩余宽度。
(3)画[540,600),已存在,跳过
(4)画[30,150)

日历时间块布局实现_第6张图片
image.png

代码实现:

- (void)drawTimeBlock {
    
    NSArray *jsonArr = @[
                         @{@"start":@"30",@"end":@"670"},
                         @{@"start":@"100",@"end":@"180"},
                         @{@"start":@"180",@"end":@"200"},
                         @{@"start":@"210",@"end":@"480"},
                         @{@"start":@"220",@"end":@"490"},
                         @{@"start":@"250",@"end":@"500"},
                         @{@"start":@"280",@"end":@"510"},
                         @{@"start":@"540",@"end":@"600"},
                         @{@"start":@"550",@"end":@"620"},
                         @{@"start":@"560",@"end":@"650"},
                         @{@"start":@"630",@"end":@"690"},
                         @{@"start":@"640",@"end":@"700"},
                         ];
    
    NSMutableArray *regionArr = [NSMutableArray array];
    NSMutableArray *beginArr = [NSMutableArray array];
    
    for (int i=0; i obj2.minNum;
        }];
        [crossRegionArr addObject:tempArr];
    }
    
    [crossRegionArr sortUsingComparator:^NSComparisonResult(NSArray *obj1, NSArray *obj2) {//数组按照count排序
        return obj1.count < obj2.count;
    }];
    
    for (int i=0; i

Region对象

@interface Region : NSObject
@property(nonatomic, assign)CGFloat minNum;
@property(nonatomic, assign)CGFloat maxNum;
@property(nonatomic, weak)UIView *associatedView;

- (BOOL)containNum:(CGFloat)num;
@end

@implementation Region
- (BOOL)containNum:(CGFloat)num {
    return (num >= self.minNum && num < self.maxNum);
}
@end

运行结果

日历时间块布局实现_第7张图片
三组测试数据运行结果

github地址: https://github.com/liugangios/timeline.git

你可能感兴趣的:(日历时间块布局实现)