时间轴的制作

制作时间轴时最重要的是计算下一个圆点及时间轴的长度

1.计算高度可以按取出的当前模型的内容计算,如下:

1
2
3
4
5
6
7
//取出的每个模型
 GTimeLineViewModel *timeLimeM = dataArray[i];
 //设置内容     
 NSString *content = timeLimeM.text;
//计算高度,注意这里的宽度很关键,将会控制你文字设置的高度,options设置为:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
 
 CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size;

2.当计算下一个圆圈的y值时,算法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (CGFloat)iyToDataArray:(NSArray <GTimeLineViewModel *> *)dataArray toIndex:(NSInteger)index{
    CGFloat iy = 0;
    GTimeLineViewModel *viewModel;
    if (index > 0) {
        CGFloat contentH = 0;
 
//计算下一个圆圈,关键点就在这里,当i=1公式为上一个的圆圈+上一个时间轴的高度,当i //== 2时公式为:
//(i- 1)+(i - 2)内容的高度,当i == 3时公式为:
//(i- 1)+(i - 2)+(i-3)内容的高度等等。
        for (NSInteger i = index; i > 0; i--) {
             viewModel= [dataArray objectAtIndex:(i-1)];
            NSString *content = viewModel.text;
            CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[self FontSizeHeight:14]} context:nil].size;
            contentH = contentH+size.height;
        }
//        CGFloat textH = [self compareHeigth:contentH];
        iy = index * (KTIMELINEAUX_WH_CIRCLE+ 2*[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE]+KTIMELINEAUX_WGAP_LEFT)+contentH;
    }else{//为0时,y值 就是0
        viewModel = dataArray[index];
        NSString *content = viewModel.text;
        CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[self FontSizeHeight:14]} context:nil].size;
        iy = index * (KTIMELINEAUX_WH_CIRCLE+size.height+ 2*[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE]+KTIMELINEAUX_WGAP_LEFT);
    }
    return iy;
}

 

3.下面就时间轴制作的整套代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#define  TIME_SCERRN_WIDTH [UIScreen mainScreen].bounds.size.width
#define  TIME_SCERRN_HEIGHT [UIScreen mainScreen].bounds.size.height
#import "GTimeLineView.h"
#import "GTimeLineViewModel.h"
#import "KTimeLineAux.h"
#import "UIImage+Custom.h"
@interface GTimeLineView(){
 
    UILabel *_circleL; //圆圈
    UILabel *_lineL;   //竖线
    UILabel *_twoCircleL; //圆圈2
    UILabel *_timeL;  //时间label
    UIImageView *_conentImageV; //存储label文字
    UILabel *_conentL;  //label文字
    KTimeLineAux *_ktimeLineAux;
     
}
@end
@implementation GTimeLineView
 
 
- (void)timeLineViewWithFrame:(CGRect)frame reloadDataWithArray:(NSArray<GTimeLineViewModel *> *)dataArray{
 
    if (dataArray && dataArray.count > 0) {
        [self loadUI:frame];
        for (NSInteger i = 0; i < dataArray.count; i++) {
            id sub = dataArray[i];
            if (![sub isKindOfClass:[GTimeLineViewModel class]]) {
                return;
            }
            GTimeLineViewModel *timeLimeM = dataArray[i];
        
            NSString *content = timeLimeM.text;
            if (!content.length) {
                return;
            }
            CGFloat imageW = [self getImageViewWidth];
             
            CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size;
            //线的高度
            CGFloat lineHeight = 2*[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE]+size.height+KTIMELINEAUX_WGAP_LEFT;
             
            CGFloat circleY = [self iyToDataArray:dataArray toIndex:i];
         
             
            [self setFrame:frame];
            //one circle
            _circleL = [[UILabel alloc] initWithFrame:CGRectMake(frame.origin.x,circleY,KTIMELINEAUX_WH_CIRCLE, KTIMELINEAUX_WH_CIRCLE)];
            [self setCornerRadiusWithLabel:_circleL];
            _circleL.layer.borderColor = [self sixtyTwoColor].CGColor;
            _circleL.layer.borderWidth = 2;
            
            //line
            
            _lineL = [[UILabel alloc] initWithFrame:CGRectMake(_circleL.center.x-KTIMELINEAUX_WIDTH_LINE/2,CGRectGetMaxY(_circleL.frame),KTIMELINEAUX_WIDTH_LINE,lineHeight)];
            [_lineL setBackgroundColor:[self sixtyTwoColor]];
             
             
            //time
            _timeL = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_circleL.frame)+[_ktimeLineAux kTimeLineAuxScaleWidth:KTIMELINEAUX_WGAP_CIRCLE_TIME],CGRectGetMinY(_circleL.frame)-2,KTIMELINEAUX_WIDTH_TIME_LABEL,KTIMELINEAUX_HEIGHT_TIME_LABEL)];
            [_timeL setTextColor:[self sixtyTwoColor]];
            _timeL.text = timeLimeM.time;
            [_timeL setFont:[self FontSizeHeight:16]];
            _timeL.textAlignment = NSTextAlignmentLeft;
             
            //image
             
            _conentImageV = [[UIImageView alloc] initWithFrame:CGRectMake([_ktimeLineAux kTimeLineAuxScaleWidth:KTIMELINEAUX_WGAP_IMAGE_LEFT],CGRectGetMaxY(_circleL.frame)+[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE],imageW,size.height+10)];
            _conentImageV.image = [UIImage resizeableImageWithName:@"timeImage"];
             
            _conentL = [[UILabel alloc] initWithFrame:CGRectMake(KTIMELINEAUX_WGAP_LEFT, KTIMELINEAUX_WGAP_LEFT,CGRectGetWidth(_conentImageV.frame)-2*KTIMELINEAUX_WGAP_LEFT, size.height)];
            _conentL.numberOfLines = 0;
            _conentL.lineBreakMode = NSLineBreakByCharWrapping;
            _conentL.text = content;
            [_conentL setTextColor:[self fivtyOneColor]];
            [_conentImageV addSubview:_conentL];
        
             
            if (i == dataArray.count -1) {
                _twoCircleL = [[UILabel alloc] initWithFrame:CGRectMake(frame.origin.x,CGRectGetMaxY(_lineL.frame),KTIMELINEAUX_WH_CIRCLE, KTIMELINEAUX_WH_CIRCLE)];
                [self setCornerRadiusWithLabel:_twoCircleL];
                _twoCircleL.layer.borderColor = [self sixtyTwoColor].CGColor;
                _twoCircleL.layer.borderWidth = 2;
                [_twoCircleL setBackgroundColor:[UIColor clearColor]];
                 
                //change Frame
                CGRect selfF = self.frame;
                selfF.size.height = CGRectGetMaxY(_twoCircleL.frame)+10;
                self.frame = selfF;
                 
//                [self setContentSize:CGSizeMake(frame.size.width,3000)];
            }
//            [_scrollView addSubview:self];
            [self addSubview:_circleL];
            [self addSubview:_lineL];
            [self addSubview:_twoCircleL];
            [self addSubview:_timeL];
            [self addSubview:_conentImageV];
            [self addSubview:_twoCircleL];
            NSLog(@"\n_circleL= %@\n_lineL =%@\n_timeL=%@\n_conentImageV=%@\n_twoCircleL=%@\nself=%@\n",_circleL,_lineL,_timeL,_conentImageV,_twoCircleL,self);
             
        }
    }
 
}
#pragma mark --- loadUI
- (void)loadUI:(CGRect)frame{
    _ktimeLineAux = [KTimeLineAux shareTimeLineAux];
     
    CGFloat iy = 0;
    if (frame.size.height <TIME_SCERRN_HEIGHT) {
        iy = TIME_SCERRN_HEIGHT;
    }else{
        iy = frame.size.height;
    }
}
#pragma mark --- font
- (UIFont*)FontSizeHeight:(CGFloat)height{
     
    return [UIFont systemFontOfSize:height];
}
#pragma mark --- Radius
- (void)setCornerRadiusWithLabel:(UILabel *)label{
    label.layer.cornerRadius  = KTIMELINEAUX_WH_CIRCLE/2;
    label.layer.masksToBounds = YES;
}
#pragma mark --- color
- (UIColor *)fivtyOneColor{
    return [self colorWithR:51 G:51 B:51];
}
- (UIColor *)sixtyTwoColor{
     
    return [self colorWithR:62 G:147 B:75];
}
- (UIColor *)colorWithR:(CGFloat)r G:(CGFloat)g B:(CGFloat)b{
     
    return [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0];
}
 
//_circly iy
- (CGFloat)iyToDataArray:(NSArray <GTimeLineViewModel *> *)dataArray toIndex:(NSInteger)index{
    CGFloat iy = 0;
    GTimeLineViewModel *viewModel;
    if (index > 0) {
        CGFloat contentH = 0;
        for (NSInteger i = index; i > 0; i--) {
             viewModel= [dataArray objectAtIndex:(i-1)];
            NSString *content = viewModel.text;
            CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[self FontSizeHeight:14]} context:nil].size;
            contentH = contentH+size.height;
        }
//        CGFloat textH = [self compareHeigth:contentH];
        iy = index * (KTIMELINEAUX_WH_CIRCLE+ 2*[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE]+KTIMELINEAUX_WGAP_LEFT)+contentH;
    }else{
        viewModel = dataArray[index];
        NSString *content = viewModel.text;
        CGSize size = [content boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[self FontSizeHeight:14]} context:nil].size;
        iy = index * (KTIMELINEAUX_WH_CIRCLE+size.height+ 2*[_ktimeLineAux kTimeLineAuxScaleHeight:KTIMELINEAUX_HGAP_CIRCLE_IMAGE]+KTIMELINEAUX_WGAP_LEFT);
    }
     
     
    return iy;
}
- (CGFloat)getImageViewWidth{
     
   return (TIME_SCERRN_WIDTH - [_ktimeLineAux kTimeLineAuxScaleWidth:KTIMELINEAUX_WGAP_IMAGE_LEFT] - 2*KTIMELINEAUX_WGAP_RIGHT);
}
- (CGFloat)compareHeigth:(CGFloat)height{
     
    CGFloat h = 30;
    if (h > height)
        return h;
    else
       return  height;
}
@end
+ (UIImage *)resizeableImageWithName:(NSString *)name{
     
    UIImage *image = [UIImage imageNamed:name];
    NSInteger leftCapWidth = image.size.width *0.7;
    NSInteger topCapHeight = image.size.height *0.5;
    CGFloat left = 5;
    CGFloat right = 10;
    CGFloat top = 10;
    CGFloat bottom = 10;
    UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
     
    return [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
//    return [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
}
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface KTimeLineAux : NSObject
 
 
 
extern const NSInteger KTIMELINEAUX_WIDTH_TIME_LABEL;          //时间的宽度
extern const NSInteger KTIMELINEAUX_WIDTH_LINE;          //线的宽度
extern const NSInteger KTIMELINEAUX_WH_CIRCLE;           //圆圈的大小
 
extern const NSInteger KTIMELINEAUX_HEIGHT_TIME_LABEL;   //时间的高度
 
extern const NSInteger KTIMELINEAUX_WGAP_LEFT;          //视图左边间距
extern const NSInteger KTIMELINEAUX_WGAP_RIGHT;         //视图右边间距
extern const NSInteger KTIMELINEAUX_HGAP_CIRCLE_IMAGE;  //圆圈与存储文字的视图的上下间距
 
 
extern const NSInteger KTIMELINEAUX_WGAP_CIRCLE_TIME;    //圆圈与时间label的间距
extern const NSInteger KTIMELINEAUX_WGAP_LINE_IMAGE;     //线与存储文字视图的左右间距
extern const NSInteger KTIMELINEAUX_WGAP_IMAGE_LEFT;    //存储文字视图左边间距
extern const NSInteger KTIMELINEAUX_WGAP_IMAGE_RIGHT;   //存储文字视图右边间距
 
 
+ (KTimeLineAux *)shareTimeLineAux;
 
/**按比例获取高度*/
- (CGFloat)kTimeLineAuxScaleHeight:(CGFloat)height;
/**按比例获取宽度*/
- (CGFloat)kTimeLineAuxScaleWidth:(CGFloat)width;
@end
#define SCREEN_WIDTH ([[UIScreen mainScreen]bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen]bounds].size.height)
#define SCREEN_WIDTH_SCALE SCREEN_WIDTH/375
#define SCREEN_HEIGHT_SCALE SCREEN_HEIGHT/667
#define SCREEN_DEFAULT_HEIGHT 667
#import "KTimeLineAux.h"
 
@implementation KTimeLineAux
NSInteger const KTIMELINEAUX_WIDTH_TIME_LABEL = 100;
NSInteger const KTIMELINEAUX_HEIGHT_TIME_LABEL = 20;
 
NSInteger const KTIMELINEAUX_WIDTH_LINE = 2;
NSInteger const KTIMELINEAUX_WH_CIRCLE = 8;
 
NSInteger const KTIMELINEAUX_HGAP_CIRCLE_IMAGE = 17;
NSInteger const KTIMELINEAUX_WGAP_LEFT = 10;
NSInteger const KTIMELINEAUX_WGAP_RIGHT = 10;
NSInteger const KTIMELINEAUX_WGAP_CIRCLE_TIME = 19;
NSInteger const KTIMELINEAUX_WGAP_IMAGE_LEFT = 33;
NSInteger const KTIMELINEAUX_WGAP_IMAGE_RIGHT = 10;
 
 
+ (KTimeLineAux *)shareTimeLineAux{
 
    static KTimeLineAux *timeLine = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timeLine = [[KTimeLineAux alloc] init];
    });
    return timeLine;
}
- (CGFloat)kTimeLineAuxScaleHeight:(CGFloat)height{
    if (height<=0) {
        return 0;
    }
    CGFloat scaleH = height*SCREEN_HEIGHT_SCALE;
    return scaleH;
}
- (CGFloat)kTimeLineAuxScaleWidth:(CGFloat)width{
 
    if (width <= 0) {
        return 0;
    }
    CGFloat scaleW = width*SCREEN_WIDTH_SCALE;
    return scaleW;
}
@end

 

posted @   TheYouth  阅读(1801)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示