大家先看一下其显示效果
时间轴展示效果
看起来虽丑,但那不是重点。以上只是一个简单的例子,其实现起来方法很多,我列举出了其中能实现其效果的两种实现方式。
第一种:借助UITableView自定义UITableViewCell####
我们大致观察时间轴的UI效果,虽然显示内容不同,但样式还是有规律可循的。
首先,我们自定义LGJTimeLineCell 继承UITableViewCell
其具体实现代码如下:
LGJTimeLineCell.h
#import <UIKit/UIKit.h>
@class LGJTimeLineModel;
@interface LGJTimeLineCell : UITableViewCell
@property(nonatomic,copy)NSString *numberStr;
@property(nonatomic,strong)LGJTimeLineModel *model;
-(void)setUITopViewShow:(BOOL)topLineShow bottomViewShow:(BOOL)bottomLineShow;
@end
LGJTimeLineCell.m
#import "LGJTimeLineCell.h"
#import "LGJTimeLineModel.h"
@interface LGJTimeLineCell ()
@property (weak, nonatomic) IBOutlet UIView *topLine;
@property (weak, nonatomic) IBOutlet UIButton *circleButton;
@property (weak, nonatomic) IBOutlet UIView *bottomLine;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *contentLabel;
@end
@implementation LGJTimeLineCell
- (void)awakeFromNib {
[super awakeFromNib];
self.circleButton.layer.cornerRadius = 15.0f;
self.circleButton.layer.masksToBounds = YES;
}
-(void)setUITopViewShow:(BOOL)topLineShow bottomViewShow:(BOOL)bottomLineShow{
self.topLine.hidden = topLineShow ? YES : NO;
self.bottomLine.hidden = bottomLineShow ? YES : NO;
}
-(void)setNumberStr:(NSString *)numberStr{
[self.circleButton setTitle:numberStr forState:UIControlStateNormal];
}
-(void)setModel:(LGJTimeLineModel *)model{
self.titleLabel.text = model.title;
self.contentLabel.text = model.content;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
创建展示模型类
#import <Foundation/Foundation.h>
@interface LGJTimeLineModel : NSObject
@property(nonatomic,copy)NSString *title;
@property(nonatomic,copy)NSString *content;
@end
接下来借助tableView的展示,并实现其数据源和代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.dataSourse count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
LGJTimeLineModel *model = self.dataSourse[indexPath.row];
LGJTimeLineCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LGJTimeLineCell"];
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:@"LGJTimeLineCell" owner:nil options:nil]lastObject];
}
cell.model = model;
[cell setUITopViewShow:NO bottomViewShow:NO];
if (indexPath.row == 0) {
[cell setUITopViewShow:NO bottomViewShow:YES];
}
if (indexPath.row == [self.dataSourse count] - 1) {
[cell setUITopViewShow:YES bottomViewShow:NO];
}
cell.numberStr = [NSString stringWithFormat:@"%ld",indexPath.row + 1];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
LGJTimeLineModel *model = self.dataSourse[indexPath.row];
CGFloat title_Height = [self returnHeightWithString:model.title font:[UIFont systemFontOfSize:15]];
CGFloat content_Height = [self returnHeightWithString:model.content font:[UIFont systemFontOfSize:13]];
return title_Height + content_Height + 60;
}
-(CGFloat)returnHeightWithString:(NSString *)str font:(UIFont *)font{
return [str boundingRectWithSize:CGSizeMake(self.view.frame.size.width - 70, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size.height;
}
第二种:借助UIScollView的滚动特性添加子视图完成####
首先自定义LGJTimelineView类
LGJTimelineView.h
#import <UIKit/UIKit.h>
@class LGJTimelineView;
@protocol LGJTimelineViewDelegate <NSObject>
- (void)clickedViewWithTimelineView:(LGJTimelineView *)timelineView sender:(UIButton *)sender;
@end
@interface LGJTimelineView : UIView
@property(nonatomic,weak)id<LGJTimelineViewDelegate> delegate;
-(void)setContentWithTitleArray:(NSArray *)titleArray contentArray:(NSArray *)contentArray scollView:(UIScrollView *)scollView titleFont:(UIFont *)titleFont contentFont:(UIFont *)contentFont;
@end
LGJTimelineView.m
#import "LGJTimelineView.h"
#define kColor(hex) [UIColor colorWithRed:((CGFloat)((hex & 0xFF0000) >> 16)) / 255.0 green:((CGFloat)((hex & 0xFF00) >> 8)) / 255.0 blue:((CGFloat)(hex & 0xFF)) / 255.0 alpha:1]
// 起始位置的Y
#define Start_Position_Y 0
// 起始位置的X
#define Start_Position_X 15
// 直径
#define Round_Directly 23
// 连接的线长
#define Line_Length 88
@implementation LGJTimelineView
-(void)setContentWithTitleArray:(NSArray *)titleArray contentArray:(NSArray *)contentArray scollView:(UIScrollView *)scollView titleFont:(UIFont *)titleFont contentFont:(UIFont *)contentFont{
CGFloat content_H = 0;
CGFloat view_H = 0;
for (NSInteger i = 0; i < [titleArray count]; i++) {
CGFloat content_Width = self.frame.size.width - Round_Directly -Start_Position_X * 3;
CGFloat content_Height = [self calculteTheSizeWithContent:contentArray[i] rect:CGSizeMake(content_Width, MAXFLOAT) font:[UIFont systemFontOfSize:14]].height;
CGFloat labelH = content_Height + Round_Directly;
content_H += labelH ;
view_H += content_Height;
CGFloat contentY = Start_Position_Y + content_H - labelH + ( Round_Directly) * (i+1);
// 阶段
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(Start_Position_X, contentY, Round_Directly, Round_Directly)];
btn.layer.cornerRadius = Round_Directly * 0.5;
btn.layer.masksToBounds = YES;
btn.layer.borderColor = kColor(0x358fd7).CGColor;
btn.layer.borderWidth = 1;
[btn setTitle:[NSString stringWithFormat:@"%ld", i + 1] forState:UIControlStateNormal];
[btn setTitleColor:kColor(0x358fd7) forState:UIControlStateNormal];
btn.tag = i + 1;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
// 标题
UILabel *titleLable = [self lableWithFrame:CGRectMake(CGRectGetMaxX(btn.frame) + 15, CGRectGetMidY(btn.frame) - Round_Directly*0.5,content_Width , Round_Directly) text:titleArray[i] textColor:kColor(0x358fd7) font:19];
titleLable.numberOfLines = 0;
[self addSubview:titleLable];
// 内容
UILabel *contentlable = [self lableWithFrame:CGRectMake(CGRectGetMinX(titleLable.frame), CGRectGetMaxY(titleLable.frame) + Round_Directly * 0.5, titleLable.frame.size.width, content_Height) text:contentArray[i] textColor:kColor(0x666666) font:14];
contentlable.numberOfLines = 0;
[self addSubview:contentlable];
// 连接线
if (i < contentArray.count - 1) {
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(Start_Position_X + Round_Directly * 0.5 - 0.5,CGRectGetMaxY(titleLable.frame) , 1, labelH)];
lineView.backgroundColor = kColor(0x358fd7);
[self addSubview:lineView];
}
}
CGFloat H = Start_Position_Y + view_H + Round_Directly * titleArray.count * 2 + Round_Directly * 0.5;
scollView.contentSize = CGSizeMake(self.frame.size.width, H);
}
- (UILabel *)lableWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(NSInteger)font {
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.text = text;
label.textColor = textColor;
label.font = [UIFont systemFontOfSize:font];
label.textAlignment = NSTextAlignmentLeft;
return label;
}
- (CGSize)calculteTheSizeWithContent:(NSString*)content rect:(CGSize)rect font:(UIFont*)font {
NSDictionary *attribute = @{NSFontAttributeName: font};
CGSize size = [content boundingRectWithSize:rect options:
NSStringDrawingTruncatesLastVisibleLine |
NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingUsesFontLeading
attributes:attribute
context:nil].size;
return size;
}
- (void)btnClick: (UIButton *)sender {
if ([self.delegate respondsToSelector:@selector(clickedViewWithTimelineView:sender:)]) {
[self.delegate clickedViewWithTimelineView:self sender:sender];
}
}
其使用也是非常简单,在我们需要的地方直接调用,至于UI丑美,这个根绝个人情况来:
LGJTimelineView *timeLineView = [[LGJTimelineView alloc] initWithFrame:self.view.bounds];
[timeLineView setContentWithTitleArray:self.titleArray contentArray:self.contentArray scollView:scrollView titleFont:[UIFont systemFontOfSize:15] contentFont:[UIFont systemFontOfSize:13]];
timeLineView.delegate = self;
[scrollView addSubview:timeLineView];
}
- (void)clickedViewWithTimelineView:(LGJTimelineView *)timelineView sender:(UIButton *)sender{
NSLog(@"%ld",sender.tag);
}
其实现效果如下:
第二种
网友评论