iOS 照片时间轴

iOS 照片时间轴下载地址 : http://download.csdn.net/detail/lovechris00/9592374


这两天看别人的时间轴效果,感觉有兴趣,不过代码不符合我的风格,就想自己重写一个,本以为一个小时就可以搞定,没想到写了三四个小时,在此分享,效果如下:




零、基本思路:


1、将日数据和月数据分别创建两个Model来方便传值:LineDayModel , LineMonthModel;

2、使用tableView展示数据,每一行的数据由一个模型决定:LineDisplayModel;

3、月份数据作为组头,每一组有多少行由每一天的照片占用的列数决定。



一、UI界面部分


1、创建tableView,并定义部分样式


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (UITableView *)tableView{  
  2.     //    WS(weakSelf);  
  3.     if (!_tableView) {  
  4.           
  5.         _tableView =[[UITableView alloc]initWithFrame:CGRectMake(0,0, kSCREEN_WIDTH, kSCREEN_HEIGHT) style: UITableViewStyleGrouped];  
  6.           
  7.         _tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];  
  8.           
  9.         [_tableView registerNib:[TimeOneCell nib] forCellReuseIdentifier:cellTimeOne];  
  10.         [_tableView registerNib:[TimeTwoCell nib] forCellReuseIdentifier:cellTimeTwo];  
  11.           
  12.         [_tableView setSeparatorColor:[UIColor lightGrayColor]];  
  13.         _tableView.tableFooterView = [UIView new];  
  14.         _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;  
  15.       
  16.         _tableView.delegate = self;  
  17.         _tableView.dataSourceself;  
  18.           
  19.         [self.view addSubview:_tableView];  
  20.     }  
  21.     return _tableView;  
  22. }  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{  
  2.       
  3.     return 86;  
  4.       
  5. }  
  6.   
  7. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{  
  8.       
  9.     return 44;  
  10. }  
  11.   
  12. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{  
  13.       
  14.     return 20;  
  15. }  



2、自定义组头


继承自UIView,并添加Xib文件





3、自定义两种UITableViewCell




数据处理方法

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)refreshUIWithImageArray:(NSArray *)array time:(NSString *)time  
  2. {  
  3.     self.timeLabel.text = time;  
  4.       
  5.     if (array.count > 0) {  
  6.         self.imgView1.image = [UIImage imageNamed:array[0]];  
  7.     }  
  8.       
  9.     if (array.count > 1) {  
  10.         self.imgView2.image = [UIImage imageNamed:array[1]];  
  11.     }  
  12.       
  13.     if (array.count > 2) {  
  14.         self.imgView3.image = [UIImage imageNamed:array[2]];  
  15.     }  
  16. }  







数据处理方法:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)refreshUIWithImageArray:(NSArray *)array  
  2. {  
  3.     if (array.count > 0) {  
  4.         self.imgView1.image = [UIImage imageNamed:array[0]];  
  5.     }  
  6.       
  7.     if (array.count > 1) {  
  8.         self.imgView2.image = [UIImage imageNamed:array[1]];  
  9.     }  
  10.       
  11.     if (array.count > 2) {  
  12.         self.imgView3.image = [UIImage imageNamed:array[2]];  
  13.     }  
  14. }  



二、数据部分


1、创建LineDisplayModel 传递tableView每一行的数据;


其中,isFirst决定 是否为这个tableview的第一行(即显示日期的这一行),如下:



.h文件

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface LineDisplayModel : NSObject  
  4. @property (nonatomic,assign) BOOL isFirst;  
  5. @property (nonatomic,copyNSString *day;  
  6. @property (nonatomic,strongNSMutableArray *imgArray;  
  7. @end  

.m文件 不做任何数据处理



2、创建LineDayModel 接收每日的照片、日期;


其中,dayRow 用来计算本日照片占用多少行;如果0-3张照片,占用一行;4-6张照片,占用两行....

并把每一行的照片信息,赋值给LineDisplayModel,将displayModel组成displayArray


.h文件

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface LineDayModel : NSObject  
  4. @property (nonatomic,copyNSString *day;  
  5. @property (nonatomic,strongNSArray *imgArray;  
  6.   
  7. @property (nonatomic,assign) int dayRows;  
  8. @property (nonatomic,strongNSMutableArray *displayArray;  
  9.   
  10. - (instancetype)initWithDay:(NSString *)day imgArray:(NSArray *)imgArray;  
  11.   
  12. @end  


.m文件

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import "LineDayModel.h"  
  2. #import "LineDisplayModel.h"  
  3.   
  4. @implementation LineDayModel  
  5. - (instancetype)initWithDay:(NSString *)day imgArray:(NSArray *)imgArray  
  6. {  
  7.     self = [super init];  
  8.    
  9.     self.day = day;  
  10.     self.imgArray = imgArray;  
  11.   
  12.     self.dayRows = 0;  
  13.       
  14.     if (self.imgArray.count % 3 != 0) {  
  15.         self.dayRows = self.imgArray.count / 3 + 1;  
  16.     }else{  
  17.         self.dayRows = self.imgArray.count / 3 ;  
  18.     }  
  19.       
  20. //    NSLog(@"dayRows : %d",self.dayRows);  
  21.       
  22.       
  23.     for (int m = 0; m < self.dayRows; m++) {  
  24.         LineDisplayModel *pModel = [[LineDisplayModel alloc]init];  
  25.         pModel.imgArray = [[NSMutableArray alloc]init];  
  26.           
  27.         if (m == 0) {  
  28.             pModel.isFirst = YES;  
  29.             pModel.day = self.day;  
  30.         }else{  
  31.             pModel.isFirst = NO;  
  32.             pModel.day = @"";  
  33.         }  
  34.           
  35.           
  36.         for (int n = 0; n < 3; n++) {  
  37.               
  38.             
  39.             if (self.imgArray.count > m * 3 + n) {  
  40. //                  NSLog(@"m : %d , n : %d , index : %d",m,n,m * 3 + n);  
  41.                 [pModel.imgArray addObject:self.imgArray[m * 3 + n]];  
  42.             }  
  43.               
  44.         }  
  45.           
  46. //        NSLog(@"pModel : %d , %@ , %@",pModel.isFirst,pModel.day,pModel.imgArray);  
  47.           
  48.         [self.displayArray addObject:pModel];  
  49.     }  
  50.       
  51. //    NSLog(@"该天行数 : %d",self.dayRows);  
  52.    
  53.     return self;  
  54. }  
  55.   
  56. -(NSMutableArray *)displayArray  
  57. {  
  58.     if (!_displayArray) {  
  59.         _displayArray = [[NSMutableArray alloc]init];  
  60.     }  
  61.     return _displayArray;  
  62. }  


3、创建LineMonthModel 接收每月下面每日的信息汇总;


其中 days 作为接收 LineDayModel 的数组;

monthRows 将每日的行数加起来;

displayArray 将每日的 LineDisplayModel 加起来;

shouldOpen 决定在tableView上的开关状态;


.h文件:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface LineMonthModel : NSObject  
  4.   
  5. @property (nonatomic,copyNSString *month;  
  6. @property (nonatomic,strongNSMutableArray *days;  
  7. @property (nonatomic,assign) int monthRows;  
  8. @property (nonatomic,assign) BOOL shouldOpen;  
  9. @property (nonatomic,strongNSMutableArray *displayArray;  
  10.   
  11. - (instancetype)initWithMonth:(NSString *)month days:(NSArray *)days;  
  12.   
  13. @end  

.m文件

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import "LineMonthModel.h"  
  2. #import "LineDayModel.h"  
  3. #import "LineDisplayModel.h"  
  4.   
  5. @implementation LineMonthModel  
  6.   
  7. - (instancetype)initWithMonth:(NSString *)month days:(NSArray *)days  
  8. {  
  9.     self = [super init];  
  10.     self.month = month;  
  11.     self.days = [NSMutableArray arrayWithArray:days];  
  12.     self.monthRows = 0;  
  13.       
  14.     self.displayArray = [[NSMutableArray alloc]init];  
  15.       
  16.     for (int i = 0; i< self.days.count; i++) {  
  17.           
  18.         LineDayModel *dModel = self.days[i];  
  19.         self.monthRows = self.monthRows + dModel.dayRows;  
  20.         [self.displayArray addObjectsFromArray:dModel.displayArray];  
  21.   
  22.     }  
  23.       
  24.     NSLog(@"该月行数 : %d , %@",self.monthRows,self.displayArray);  
  25.       
  26.       
  27.     return self;  
  28. }  
  29.   
  30.   
  31. -(NSMutableArray *)displayArray  
  32. {  
  33.     if (!_displayArray) {  
  34.         _displayArray = [[NSMutableArray alloc]init];  
  35.     }  
  36.     return _displayArray;  
  37. }  


4、初始化照片、时间数据


在CSTimeLineViewController.h 中

将dataArray 作为成员变量,并接收所有的月份数据。

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)initData{  
  2.       
  3.     LineDayModel *lModel00 = [[LineDayModel alloc]initWithDay:@"5.1" imgArray:@[@"1",@"2"]];  
  4.     LineDayModel *lModel01 = [[LineDayModel alloc]initWithDay:@"5.2" imgArray:@[@"1",@"2",@"3",@"4",@"1"]];  
  5.     LineDayModel *lModel02 = [[LineDayModel alloc]initWithDay:@"5.3" imgArray:@[@"1",@"2",@"1"]];  
  6.       
  7.     LineMonthModel *lmModel0 = [[LineMonthModel alloc]initWithMonth:@"2016年5月" days:@[lModel00,lModel01]];  
  8.       
  9.       
  10.     LineDayModel *lModel10 = [[LineDayModel alloc]initWithDay:@"6.1" imgArray:@[@"1",@"3",@"1"]];  
  11.     LineDayModel *lModel11 = [[LineDayModel alloc]initWithDay:@"6.2" imgArray:@[@"1",@"2",@"4"]];  
  12.       
  13.       
  14.     LineMonthModel *lmModel1 = [[LineMonthModel alloc]initWithMonth:@"2016年6月" days:@[lModel10,lModel11]];  
  15.       
  16.       
  17.     LineDayModel *lModel20 = [[LineDayModel alloc]initWithDay:@"7.1" imgArray:@[@"2",@"3",@"1",@"3",@"1"]];  
  18.     LineDayModel *lModel21 = [[LineDayModel alloc]initWithDay:@"7.2" imgArray:@[@"3",@"2",@"1",@"3",@"1",@"3",@"1",@"3",@"1"]];  
  19.       
  20.     LineMonthModel *lmModel2 = [[LineMonthModel alloc]initWithMonth:@"2016年7月" days:@[lModel20,lModel21]];  
  21.       
  22.     self.dataArray = [NSMutableArray arrayWithArray:@[lmModel0,lmModel1,lmModel2]];  
  23.       
  24.     for (LineMonthModel *mModel in self.dataArray) {  
  25.         mModel.shouldOpen = YES;  
  26.     }  
  27.       
  28.     NSLog(@"dataArray : %@",self.dataArray);  
  29.       
  30. }  


5、tableView上的显示


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{  
  2.       
  3.     return self.dataArray.count;  
  4. }  
  5.   
  6. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{  
  7.       
  8.     LineMonthModel *mModel =self.dataArray[section];  //五月  
  9.       
  10.     if (mModel.shouldOpen) {  
  11.         return mModel.monthRows;  
  12.     }  
  13.       
  14.     return 0;  
  15. }  
  16.   
  17.   
  18. -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section  
  19. {  
  20.     TimeHeader *header = [[TimeHeader alloc]init];  
  21.       
  22.     LineMonthModel *mModel =self.dataArray[section];  
  23.       
  24.     header.timeLabel.text = mModel.month;  
  25.     header.btn.tag = section;  
  26.       
  27.     if (mModel.shouldOpen) {  
  28.         [header.btn setTitle:@"关闭" forState:UIControlStateNormal];  
  29.           
  30.     }else{  
  31.         [header.btn setTitle:@"打开" forState:UIControlStateNormal];  
  32.     }  
  33.       
  34.     [header.btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];  
  35.       
  36.     return header;  
  37. }  
  38.   
  39. - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{  
  40.       
  41.     UITableViewCell * cell;  
  42.       
  43.     LineMonthModel *mModel =self.dataArray[indexPath.section];  
  44.     LineDisplayModel *dModel = mModel.displayArray[indexPath.row];  
  45.       
  46.     NSLog(@"%@  isFirst : %d , imgArray : %@",dModel.day,dModel.isFirst,dModel.imgArray);  
  47.       
  48.     if (dModel.isFirst) {  
  49.         TimeOneCell *tempCell = [tableView dequeueReusableCellWithIdentifier:cellTimeOne];  
  50.         [tempCell refreshUIWithImageArray:dModel.imgArray time:dModel.day];  
  51.         cell = tempCell;  
  52.           
  53.     }else{  
  54.         TimeTwoCell *tempCell = [tableView dequeueReusableCellWithIdentifier:cellTimeTwo];  
  55.         [tempCell refreshUIWithImageArray:dModel.imgArray];  
  56.         cell = tempCell;  
  57.     }  
  58.     cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  59.     return cell;  
  60.       
  61. }  

6、打开/关闭该月份照片的控制


本来想直接使用[self.tableView reloadData]; 来重组数据,但是这样界面变化很难看;于是只刷新单组。

这里有很多动画效果,但是感觉UITableViewRowAnimationFade 和 UITableViewRowAnimationNone 最自然,使用UITableViewRowAnimationTop 和 UITableViewRowAnimationMiddle 会有卡顿的效果,同学们可以尝试下。


typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
    UITableViewRowAnimationFade,
    UITableViewRowAnimationRight,           // slide in from right (or out to right)
    UITableViewRowAnimationLeft,
    UITableViewRowAnimationTop,
    UITableViewRowAnimationBottom,
    UITableViewRowAnimationNone,            // available in iOS 3.0
    UITableViewRowAnimationMiddle,          // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy
    UITableViewRowAnimationAutomatic = 100  // available in iOS 5.0.  chooses an appropriate animation style for you
};


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)btnAction:(UIButton *)sender{  
  2.       
  3.     LineMonthModel *lmModel = self.dataArray[sender.tag];  
  4.     lmModel.shouldOpen = !lmModel.shouldOpen;  
  5.       
  6.     [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:sender.tag] withRowAnimation:UITableViewRowAnimationFade];  
  7.     //    [self.tableView reloadData];  //使用这种方法关闭不自然  
  8.       
  9. }  



本Demo实现的内容较少,还可以添加拍照上传、删除图片、查看大图等功能,欢迎大家丰富。


iOS 照片时间轴下载地址 : http://download.csdn.net/detail/lovechris00/9592374


1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值