【问题标题】:Sorting table sections by NSDate按 NSDate 对表格部分进行排序
【发布时间】:2015-03-01 12:42:42
【问题描述】:

我如何对NSDate 进行排序,以便如果某个日期的时间是周日早上 05:00,它会停留在周六“晚上”,但在列表中排在最后?

我从 JSON 数据中按日期对我的 tableview 部分进行排序

[[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:@"fodboldStream", @"command", nil] onCompletion:^(NSDictionary *json) {

    //got stream
    //NSLog(@"%@",json);
    [[API sharedInstance] setSoccer: [json objectForKey:@"result" ]];

    games = [json objectForKey:@"result"];


    sections = [NSMutableDictionary dictionary];

    for (NSDictionary *game in games) {
        NSNumber *gameType = game[@"dato"];
        NSMutableArray *gamesForType = sections[gameType];
        if (!gamesForType) {
            gamesForType = [NSMutableArray array];
            sections[gameType] = gamesForType;
        }
        [gamesForType addObject:game];


    }
   // NSLog(@"%@",sections);

    [fodboldTabel reloadData];
}];

这是我的部分标题:

- (NSString*) tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section {

    //...if the scetions count is les the 1 set title to opdating ...

    if ([[self.sections valueForKey:[[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:section]] count] < 1) {
        return @"Opdater....";

    } else {

        // ..........seting tabelheader titel to day and date..................
        NSString *str = [[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:section];

        NSDate *date = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ; // here we create NSDateFormatter object for change the Format of date..
        [dateFormatter setDateFormat:@"yyyy-MM-dd"]; //// here set format of date which is in your output date (means above str with format)
        date = [dateFormatter dateFromString:str];

        dateFormatter.locale=[[NSLocale alloc] initWithLocaleIdentifier:@"da_DK"];

        dateFormatter.dateFormat=@"MMMM";
        NSString * monthString = [[dateFormatter stringFromDate:date] capitalizedString];

        dateFormatter.dateFormat=@"EEEE";
        NSString * dayString = [[dateFormatter stringFromDate:date] capitalizedString];

        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSInteger units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday;
        NSDateComponents *components = [calendar components:units fromDate:date];

        NSInteger year = [components year];
        //  NSInteger month=[components month];       // if necessary
        NSInteger day = [components day];
        //NSInteger weekday = [components weekday]; // if necessary


        NSString *sectionLbl = [NSString stringWithFormat: @"%@ %li %@ %li", dayString, (long)day, monthString, (long)year];
        return sectionLbl;
    }
}

这是一张图片,你可以看到标题写着 søndag(星期日),比赛从上午 1:35 开始,所以比赛在周日早上的电视上播放,但我希望在周六播出。部分.....所以实际上我只是看着“一天”从早上 5 点到凌晨 5 点而不是 00:00 - 00:00

【问题讨论】:

  • "...如果某个日期的时间是星期六早上 05:00,它会停留在星期六的“晚上”,但在列表中是最后一个。”目前还不清楚你在问什么。也许只是向我们展示一个示例(a)输入数据的样子; (b) 你希望输出的样子。
  • 您有问题吗?
  • 我如何让“一天”从早上 5 点到凌晨 5 点而不是 00:00 - 00:00
  • 与那些时代相比。或者虚设一个相差 5 小时的时区。

标签: ios objective-c uitableview nsdate


【解决方案1】:

您应该确定timeZoneNSDateFormatter 一起使用,以便在构造节标题时使用。

例如,下面我展示了一系列事件,按when 属性排序,除了部分标题将位于某个预定时区,而不是我的设备的特定时区。所以,我首先使用适当的NSTimeZone 的日期格式化程序构建我的模型来支持我的表(一个Section 对象数组,每个对象都有一个items 数组):

// Given some array of sorted events ...

NSArray *sortedEvents = [events sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"when" ascending:YES]]];

// Let's specify a date formatter (with timezone) for the section headers.

NSDateFormatter *titleDateFormatter = [[NSDateFormatter alloc] init];
titleDateFormatter.dateStyle = NSDateFormatterLongStyle;
titleDateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];   // use whatever you want here; I'm just going to figure out sections in GMT even though I'm currently in GMT-5

// Now let's build our array of sections (and the list of events in each section)
// using the above timezone to dictate the sections.

self.sections = [NSMutableArray array];

NSString *oldTitle;
for (Event *event in sortedEvents) {
    NSString *title = [titleDateFormatter stringFromDate:event.when]; // what should the section title be

    if (![oldTitle isEqualToString:title]) {                          // if different than last one, add new section
        [self.sections addObject:[Section sectionWithName:title]];
        oldTitle = title;
    }

    [[(Section *)self.sections.lastObject items] addObject:event];    // add event to section
}

但是,当我显示单元格内容时,如果我不触摸timeZone 参数,它将默认显示当前时区的实际时间。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"EventCell";
    EventCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    Section *section = self.sections[indexPath.section];
    Event *event = section.items[indexPath.row];

    // This formatter really should be class property/method, rather than instantiating 
    // it each time, but I wanted to keep this simple. But the key is that
    // I don't specify `timeZone`, so it defaults to current timezone.

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
    formatter.timeStyle = NSDateFormatterMediumStyle;

    cell.eventTimeLabel.text = [formatter stringFromDate:event.when];

    // do additional cell population as you see fit

    return cell;
}

对于节标题,使用我在构建支持此表视图的模型的例程中提出的节名称(即,使用硬编码的时区)。

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return [(Section *)self.sections[section] sectionName];
}

如您所见,时间列在当前时区中,但它们是按我在构建部分列表的代码中指定的预定NSTimeZone 分组的。

显然,我只是将 GMT 用作我的时区,但您可能希望将时区用作赛事举办地或 NBA 篮球赛的某个任意美国时区。但希望这能说明基本思想。创建部分时使用一个时区,显示实际时间时使用默认时区。

【讨论】:

  • 请原谅我这么说,但是当我试图回答您的实际问题时,使用当地时区显示事件与时间的关系让我感到有些困惑,但归类为由其他时区。我敢打赌你会收到错误报告,说这些东西显示在“错误的日子”下。如果您必须这样做,请提供一些视觉提示,表明时间实际上与该部分的日期不同(航空公司在显示降落日期与出发日期不同的航班时会优雅地处理此问题,例如红色的“+1 天” )。
  • 你使用 Event *event 和 self.sections addObject:[Section sectionWithName:title]];是 NSString 还是 NSArray 的?
  • 我有一个名为sectionsNSMutableArray,它是一个自定义Section 对象的数组(而sectionWithName 只是一个自定义类便捷方法,用于实例化Section 对象并指定部分名称/标题)。但是不要迷失在我的特定实现的杂草中:关键是在构建部分时,您使用一个 NSTimeZone 为您的 NSDateFormatter 适合您认为是“一天”的时间,但在显示实际cellForRowAtIndexPath 的时间,您可以使用本地时区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
相关资源
最近更新 更多