iOS时间轴的实现
最近项目需求,恰好要做一个时间轴,而iOS这方面时间轴的例子也比较少,我就把自己所做的例子和思路共享出来给大家,共同学习。
时间轴的具体实现效果如图1所示:
图1
第一步:看到这个图,我们想到的第一反应就是使用tableView或者CollectionView来完成,那么我这里使用的是tableView。首先,创建一个Single View Application项目,在Main.Storyboard里面拖入一个TableView(如图2所示),这里别忘记了把TableView的delegate指向ViewController。
图 2
第二步:TableView完成了,接下来就是如何自定义TableViewCell了。在项目中new file选择Cocoa Touch Class,然后选择继承自TableViewCell,然后勾选XIB file选项,命名为“TimeCourseTableViewCell”,点击创建,完成后如图3所示:
图 3
接下来,就是为这个xib文件布局,通过图4圈出来的,我们可以找出一个cell里面具有什么控件。
图 4
根据这个,我们布局出来的如图5所示,主要就是Label和View来完成布局。
图 5
其实这里肯定会有人有疑问:
1.为什么下面那个不直接用一个Button就好了呢,还要用一个View里面嵌套一个Label呢?
2.为什么"内容"的那个label还要添加一个父控件View呢?
其实,刚开始的时候,我确实也是使用简单的一个Button和一个Label以为就可以了。后来发现,莫名的出现明明设置了buttom和label的Frame,修改了Origin,却总是出现乱七八糟的位置,后来通过view嵌套在里面,改变view的位置,就完全可以实现了。这个BUG本人也不清楚,望知情人告知,谢谢。
第三步:接下来,看xib里面的TimeCourseTableViewCell.h文件里的代码:
#import <UIKit/UIKit.h> @interface TimeCourseTableViewCell : UITableViewCell @property (weak, nonatomic) IBOutlet UILabel *lbDate; //日期 @property (weak, nonatomic) IBOutlet UILabel *lbTime; //时间 @property (weak, nonatomic) IBOutlet UIView *infoView; //白色底的那个View @property (weak, nonatomic) IBOutlet UILabel *lbInfoTitle; //通知标题 @property (weak, nonatomic) IBOutlet UILabel *lbInfoContent; //通知内容 @property (weak, nonatomic) IBOutlet UIView *infoContentView; //通知内容的父View @property (weak, nonatomic) IBOutlet UILabel *lbSegment; //竖着的灰色分割线 @property (weak, nonatomic) IBOutlet UIView *receiveView; //深红色的View @property (weak, nonatomic) IBOutlet UILabel *lbReceive; //轻触收到通知 - (CGFloat)setCellHeight:(NSString *)strInfo isSameDay:(BOOL)isSame; - (void)setRidues; - (void)setClick; - (void)setNotClick; @end
TimeCourseTableViewCell.m文件里的代码:
#import "TimeCourseTableViewCell.h" @implementation TimeCourseTableViewCell @synthesize lbDate; @synthesize lbTime; @synthesize infoView; @synthesize lbInfoTitle; @synthesize lbInfoContent; @synthesize lbReceive; @synthesize receiveView; @synthesize lbSegment; @synthesize infoContentView; - (void)awakeFromNib { // Initialization code } /*去掉上面的日期*/ - (void)deleteDate{ lbDate.hidden = YES; CGRect timeTemp = lbTime.frame; timeTemp.origin = CGPointMake(timeTemp.origin.x, 8); lbTime.frame = timeTemp; CGRect infoViewTemp = infoView.frame; infoViewTemp.origin = CGPointMake(infoViewTemp.origin.x, 8); infoView.frame = infoViewTemp; } /*设置显示的文本高度,以确定整个tableViewCell的高度,最后返回cell高度*/ - (CGFloat)setCellHeight:(NSString *)strInfo isSameDay:(BOOL)isSame{ /*如果是同一天 则去掉上面的日期*/ if (isSame) { [self deleteDate]; } [lbInfoContent setNumberOfLines:0]; //0行,则表示根据文本长度,自动增加行数 NSString *labelText = strInfo; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:labelText]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineSpacing:5.0f];//调整行间距 [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [labelText length])]; lbInfoContent.attributedText = attributedString; [lbInfoContent sizeToFit]; //填充 //NSLog(@"%@",lbInfoContent); CGRect infoContentViewTemp = infoContentView.frame; infoContentViewTemp.size = CGSizeMake(212, lbInfoContent.frame.size.height); infoContentView.frame = infoContentViewTemp; /*设置手势点击位置*/ CGRect btnTemp = receiveView.frame; btnTemp.origin = CGPointMake(0, infoContentView.frame.origin.y + infoContentView.frame.size.height + 8 ); receiveView.frame = btnTemp; //NSLog(@"%@",receiveView); /*设置整个infoView高度*/ CGRect viewTemp = infoView.frame; viewTemp.size = CGSizeMake(viewTemp.size.width, receiveView.frame.origin.y + receiveView.frame.size.height); infoView.frame = viewTemp; //NSLog(@"%@",infoView); lbSegment.frame = CGRectMake(lbSegment.frame.origin.x, 0, 3, infoView.frame.origin.y + infoView.frame.size.height + 8); NSLog(@"HEight %f",infoView.frame.origin.y + infoView.frame.size.height + 8); return infoView.frame.origin.y + infoView.frame.size.height + 8; } /*设置圆形*/ - (void)setRidues{ lbTime.layer.cornerRadius = lbTime.frame.size.width / 2; [lbTime.layer setMasksToBounds:YES]; } /*设置点击阅读样式*/ - (void)setClick{ CGFloat R = (CGFloat) 128/255.0; CGFloat G = (CGFloat) 128/255.0; CGFloat B = (CGFloat) 128/255.0; CGFloat alpha = (CGFloat) 1.0; UIColor *ColorRGB = [ UIColor colorWithRed: R green: G blue: B alpha: alpha ]; receiveView.backgroundColor = ColorRGB; lbReceive.text = @"我已收到通知"; } /*设置未点击阅读样式*/ - (void)setNotClick{ CGFloat R = (CGFloat) 255/255.0; CGFloat G = (CGFloat) 83/255.0; CGFloat B = (CGFloat) 83/255.0; CGFloat alpha = (CGFloat) 1.0; UIColor *ColorRGB = [ UIColor colorWithRed: R green: G blue: B alpha: alpha ]; receiveView.backgroundColor = ColorRGB; lbReceive.text = @"轻触收到通知"; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end
接下来,看ViewController.m文件里的代码:
#import "ViewController.h" #import "TimeCourseTableViewCell.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITableView *messageTableView; @property int messageSum; //cell个数 @property NSArray *infoArray; //保存信息内容 @property NSMutableArray *clickArray; //记录是否已经阅读了信息 1未接收 0接收 @end @implementation ViewController @synthesize messageSum; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. /*tableView*/ [self setTableViewStyle]; messageSum = 10; self.infoArray = [[NSArray alloc] initWithObjects:@"老夫聊发少年狂,治肾亏,不含糖。", @"锦帽貂裘,千骑用康王。", @"", @"为报倾城随太守,三百年,九芝堂。酒酣胸胆尚开张,西瓜霜,喜之郎。", @"持节云中,三金葡萄糖。会挽雕弓如满月,西北望 ,阿迪王。", @"十年生死两茫茫,恒源祥,羊羊羊。", @"千里孤坟,洗衣用奇强。", @"纵使相逢应不识,补维C,施尔康。", @"夜来幽梦忽还乡,学外语,新东方。相顾无言,洗洗更健康。得年年断肠处,找工作,富士康", @"啦啦啦",nil]; self.clickArray = [[NSMutableArray alloc] initWithObjects:@"1", @"1", @"1", @"1", @"1", @"1", @"1", @"1", @"1", @"1",nil]; } #pragma mark - 设置messageTableView的背景色和去掉分割线 - (void)setTableViewStyle{ self.messageTableView.separatorStyle = UITableViewCellSeparatorStyleNone; //去掉tabelView分割线 CGFloat R = (CGFloat) 237/255.0; CGFloat G = (CGFloat) 237/255.0; CGFloat B = (CGFloat) 237/255.0; CGFloat alpha = (CGFloat) 1.0; UIColor *ColorRGB = [ UIColor colorWithRed: R green: G blue: B alpha: alpha ]; [self.messageTableView setBackgroundColor:ColorRGB]; } #pragma mark - TabelView数据源协议 //该方法指定了表格视图的行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return messageSum; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ //按时间分组,假设这里[0,2],[3,5],[6,9]是同一天 TimeCourseTableViewCell *nib = [[[NSBundle mainBundle] loadNibNamed:@"TimeCourseTableViewCell" owner:self options:nil] lastObject]; if ([indexPath row] == 0) { NSLog(@"0"); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; } else if ([indexPath row]<3) { NSLog(@"0 - 3"); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; }else if ([indexPath row] == 3){ NSLog(@"3"); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; }else if ([indexPath row] < 6){ NSLog(@"3 - 6"); NSLog(@"%f",[nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; }else if ([indexPath row] == 6){ NSLog(@"6"); NSLog(@"%f",[nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; }else if ([indexPath row] > 6){ NSLog(@"6- 9"); NSLog(@"%f",[nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]); return [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; }else return 145; } //该方法返回单元格对象,有多少行表格,则调用多少次 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *simpleIdentify = @"TimeCourse"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentify]; TimeCourseTableViewCell *nib = [[[NSBundle mainBundle] loadNibNamed:@"TimeCourseTableViewCell" owner:self options:nil] lastObject]; [nib setTag:[indexPath row]]; if ([[self.clickArray objectAtIndex:[indexPath row]] isEqualToString:@"1"]) { [nib setNotClick]; }else [nib setClick]; [nib setRidues]; UITapGestureRecognizer *Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)]; nib.receiveView.userInteractionEnabled = YES; [nib.receiveView addGestureRecognizer:Tap]; if ([indexPath row] == 0) { [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; } else if ([indexPath row]<3) { [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; }else if ([indexPath row] == 3){ [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; }else if ([indexPath row] < 6){ [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; }else if ([indexPath row] == 6){ [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:NO]; }else if ([indexPath row] > 6){ [nib setCellHeight:[self.infoArray objectAtIndex:[indexPath row]] isSameDay:YES]; } cell = nib; cell.selectionStyle = UITableViewCellSelectionStyleNone; //去掉提供的选中无颜色 return cell; } #pragma mark - TabelView代理协议 //选中事件 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"44"); } - (void)tapGesture:(UITapGestureRecognizer *)sender{ NSLog(@"接收通知"); UIView *view = sender.self.view; TimeCourseTableViewCell *cell = (TimeCourseTableViewCell *)view.superview.superview.superview; UILabel *lb = view.subviews[0]; NSString *str = @"轻触收到通知"; if ([lb.text isEqualToString:str]) { [cell setClick]; [self.clickArray setObject:@"0" atIndexedSubscript:cell.tag]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
那么,运行之后,效果如图6所示:
图 6
改一下颜色,完成如下:
至此,整个时间轴完成。
思路大概如下:
1.根据时间分组:判断是不是同一天,如果是则把上面的日期隐藏,整体布局往上移动。
2.获取点击的是哪个cell:通过给cell添加tag,那么我单击手势时候,便可以获取出cell,然后更改这个cell的样式
可能写的不是很明白,大家可以认真看一下代码。
源码地址免费下载:http://download.csdn.net/detail/junlinfushi/8345531
来自:http://www.cnblogs.com/linjianxiang/p/4213926.html