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

先来一个效果图:


后台返回数据如下:

    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对存放对象的数组排序

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容