iOS根据后台返回数据按日期分组展示

2018-07-02  本文已影响31人  wwwwwwdi

先来一个效果图:


后台返回数据如下:

    browserId = FXB201807021306343699770173193;
    medianame = 方正证券;
    browserTime = 2018-07-02T13:06:57.953;
    extent1 = {"RelationId":null};
    url = http://tt.cngold.com.cn/b201806295354463490.html;
    artCode = b201806295354463490;
    mediaid = 4991280299;
    img = http://wzimg.cngold.com.cn/wechat/2018/06/FXR_0d6643ee326f4dbc9b7b7109de30a068.png-ttlist;
    mediatype = 3;
    artTitle = 方正证券:【农业丨杨天明】益生股份(002458):减持意图降质押,轻装上阵迎春风;
    refermedia = ;
    extend2 = ;

这里我们要根据browserTime字段的日期,分别把数据处理成tableview的数据源
先看嵌套的外层model

//外层model
@interface TTSkimHistoriesOuterModel : NSObject

@property (copy, nonatomic) NSString *Date;

@property (assign, nonatomic) NSInteger TCount;

@property (strong, nonatomic) NSMutableArray *detailModelArr;

@end

内层model

//内层model
@interface TTSkimHistoriesModel : NSObject
//================================================
//              外层model需要的数据
//================================================
///标题日期
@property (copy, nonatomic) NSString *titleDate;
///记录某个日期内阅读的文章数
@property (assign, nonatomic) long tCount;
//================================================
//          浏览历史页面每个cell需要的数据
//================================================
///浏览时间
@property (copy, nonatomic) NSString *browserTime;

@property (copy, nonatomic) NSString *artCode;
///文章标题
@property (copy, nonatomic) NSString *artTitle;

@property (copy, nonatomic) NSString *browserId;
//================================================
//          传入详情页面的时候需要的其他字段
//================================================
@property (copy, nonatomic) NSString *medianame;
@property (copy, nonatomic) NSString *extent1;
@property (copy, nonatomic) NSString *url;
@property (copy, nonatomic) NSString *mediaid;
@property (copy, nonatomic) NSArray *img;
@property (assign, nonatomic) NSInteger mediatype;
@property (copy, nonatomic) NSString *refermedia;
@property (copy, nonatomic) NSString *extend2;

@end

设置好model之后,我们就要开始把原始数据转成model格式的数据了

/**
 * 把请求到的数据整理,然后放到数据源中
 */
- (void)handleDataIntoModels {
    //如果请求到的数据为空,则直接返回
    if (self.dataArr.count == 0) return;
    [self.outDataArr removeAllObjects];
    
    NSMutableArray *timeArr = [NSMutableArray array];
    //首先把原数组中数据的日期取出来放入timeArr
    [self.dataArr enumerateObjectsUsingBlock:^(TTSkimHistoriesModel *model, NSUInteger idx, BOOL *stop) {
        //这里只是根据日期判断,所以去掉时间字符串
        [timeArr addObject:divideString];
    }];
    
    //日期去重
    NSSet *set = [NSSet setWithArray:timeArr];
    NSArray *userArray = [set allObjects];
    
    //重新降序排序
    NSSortDescriptor *sd1 = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO];//yes升序排列,no,降序排列
    NSArray *descendingDateArr = [userArray sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sd1, nil]];
    
    //此时得到的descendingDateArr就是按照时间降序排好的日期数组
    
    //根据日期数组的个数,生成对应数量的外层model,外层model的detailModelArr置为空数组,放置子model(每一行显示的数据model)
    [descendingDateArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        TTSkimHistoriesOuterModel *om = [[TTSkimHistoriesOuterModel alloc]init];
        NSMutableArray *arr = [NSMutableArray array];
        om.detailModelArr = arr;
        
        [self.outDataArr addObject:om];
    }];
    
    //遍历未经处理的数组,取其中每个数据的日期,看与降序排列的日期数组相比,若日期匹配就把这个数据装到对应的外层model中
    [self.dataArr enumerateObjectsUsingBlock:^(TTSkimHistoriesModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
        for (NSString *str in descendingDateArr) {
            if([str isEqualToString:divideString]) {
                TTSkimHistoriesOuterModel *om = [self.outDataArr objectAtIndex:[descendingDateArr indexOfObject:str]];
                om.Date = str;
                [om.detailModelArr addObject:model];
            }
        }
    }];
    
    
    //把前面获取的阅读数量赋值到外层model,避免本地计算数组个数造成数据显示错误
    for (NSDictionary *dict in self.timeCountArr) {
        for (TTSkimHistoriesOuterModel *om in self.outDataArr) {
            if ([om.Date isEqualToString:dict[@"Date"]]) {
                om.TCount = [objectToString(dict[@"TCount"]) longLongValue];
            }
        }
    }
}

这里看下处理好的数据


然后我们就可以把这个数据源放置到tableview上了

  1. 设置header
    这里有个知识点:
    我们使用NSDateFormatter格式化日期的时候,传入一个当前时区的时间,获得的日期对象,都是默认的UTC标准时间,也就是说传入的时间为中国时间,得到的NSDate对象显示的时间就是格林威治时间。但是 不要害怕,因为我们可以设置时间戳的时区和地点,所以,这个日期只是LOG栏中看到落后8个小时,实际转出的时候,时间是没有问题的!
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if ([self.outDataArr isArrayEmpty]) return nil;
    UIView *headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREENWIDTH, 18)];
    headView.backgroundColor = RGBCOLOR(239, 239, 239);
    
    UILabel *timeLabel = [[UILabel alloc]init];
    timeLabel.font = TT_MEDIUM_FONT(11);
    timeLabel.textColor = UIColorFromRGB(0x333333);
    TTSkimHistoriesOuterModel *om = self.outDataArr[section];
    //获取到格式一致的时间字符串来转成date,不然date会为nil
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
#if 0
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //设置dateformatter时区和坐标,虽然设置了,但是返回的NSDate对象时间仍然少了8小时,这里需要测试8点前的时间,NSDate是否返回前一天
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh-Hans"]];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]];
    TTSkimHistoriesModel *m = [om.detailModelArr lastObject];
    NSDate *d = [dateFormatter dateFromString:m.titleDate];
#else
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    /*
     这里只传年月日,默认时间为00:00分,然后2018-06-29日期转成NSDate对象,就变为:
     2018-06-28 16:00:00 UTC 可以看出虽然设置时间戳为东八区,但是返回的日期仍然为UTC时间
     Printing description of d: 2018-06-28 16:00:00 +0000
     所以可以得出结论:
     系统存储时间是以UTC标准时间来存储的,不会直接存放相应时区的时间日期,
     我们只要时间戳设置正确的时区、地点,通过时间戳处理的时间就没问题
     */
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh-Hans"]];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]];
    NSDate *d = [dateFormatter dateFromString:om.Date];
#endif

    
    if ([NSCalendar.currentCalendar isDateInToday:d]) {
        timeLabel.text = @"今天";
    }else {
        NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
        [dateFormatter1 setDateFormat:@"M月dd日"];
        NSString *newDate = [dateFormatter1 stringFromDate:d];
        timeLabel.text = newDate;
    }
    
    [headView addSubview:timeLabel];

    [timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(headView).offset(AdaptedWidth(25));
        make.centerY.equalTo(headView);
    }];
    
    UILabel *suffixLabel = [[UILabel alloc]init];
    suffixLabel = [[UILabel alloc]init];
    suffixLabel.font = TT_MEDIUM_FONT(11);
    suffixLabel.textColor = UIColorFromRGB(0x777777);
    suffixLabel.text = [NSString stringWithFormat:@"阅读了%ld篇文章",om.TCount];
    [headView addSubview:suffixLabel];
    [suffixLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(timeLabel.mas_right).offset(10);
        make.centerY.equalTo(headView);
    }];
    
    return headView;
}
  1. 设置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TTSkimHistoriesCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TTSkimHistoriesCell"];
    if (!cell) {
        cell = [[TTSkimHistoriesCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TTSkimHistoriesCell"];
    }
    [cell cellWithModel:self.outDataArr[indexPath.section].detailModelArr[indexPath.row]];
    return cell;
}

大功告成!

附:
IOS对存放对象的数组排序

上一篇下一篇

猜你喜欢

热点阅读