从 NSDate 获取 UITableView 标题

Posted

技术标签:

【中文标题】从 NSDate 获取 UITableView 标题【英文标题】:Getting UITableView header titles from NSDate 【发布时间】:2015-03-08 19:12:39 【问题描述】:

我正在通过 MagicalRecord 使用 Core Data 中的数据填充表格视图。我希望表格视图按时间顺序显示,按日期划分,也按时间顺序显示。

首先,我从 transDate 中获取 sortDate,来自我在网上找到的修改代码:

// Gives beginning of this day
- (NSDate *)sortDateForDate:(NSDate *)inputDate

    // Use the current calendar and time zone
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
    [calendar setTimeZone:timeZone];

    // Selectively convert the date components (year, month, day) of the input date
    NSDateComponents *dateComps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:inputDate];

    // Set the time components manually
    [dateComps setHour:0];
    [dateComps setMinute:0];
    [dateComps setSecond:0];

    // Convert back
    NSDate *beginningOfDay = [calendar dateFromComponents:dateComps];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterFullStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];

    NSString *beginningOfDayText = [formatter stringFromDate:beginningOfDay];

    NSLog(@"The sortDate should be %@",beginningOfDayText);

    return beginningOfDay;

然后我组装并保存新交易:

-(void) assembleAndSaveTransaction

    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];

    self.thisTransaction.transDate = [NSDate date];
    self.thisTransaction.paidTo = self.noteField.text;
    self.thisTransaction.forWhat = self.forWhatField.text;

    // Call to obtain sortDate, method above
    self.thisTransaction.sortDate = [self sortDateForDate:self.thisTransaction.transDate];

    [localContext MR_saveToPersistentStoreAndWait];

接下来,我获取所有交易,按属性“sortDate”分组并按属性“transDate”排序。

- (void)viewDidLoad

    [super viewDidLoad];

    transactionFRC = [WMMGTransaction MR_fetchAllGroupedBy:@"sortDate" withPredicate:nil sortedBy:@"transDate" ascending:NO];


然后,我将 sortDate 转换为字符串并将其分配给标题标题:

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

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterFullStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];

    NSString *sectionLabel = [formatter stringFromDate:[transactionFRC.sections objectAtIndex:section]];

    NSLog(@"The sortDate is %@",[formatter stringFromDate:[transactionFRC.sections objectAtIndex:section]]);
    NSLog(@"The sectionLabel should be %@",sectionLabel);

    return sectionLabel;

表格视图的显示方式如下:

数据似乎正确分组和排序。节标题出现在按时间顺序排列的适当位置。但是标题标题没有出现。

当我将这段代码放在带有相关TableView的VC的viewDidLoad方法中时:

NSLog(@"The header dates are as follows:\n");

for (NSDate *headerDate in [transactionFRC sections])

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterFullStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];

    NSLog(@"The sortDate is %@",[formatter stringFromDate:headerDate]);

我看到了这个读数:

2015-03-08 12:06:00.502 WheredMyMoneyGo[5374:7322757] The header dates are as follows:
2015-03-08 12:06:00.503 WheredMyMoneyGo[5374:7322757] The sortDate is (null)
2015-03-08 12:06:00.503 WheredMyMoneyGo[5374:7322757] The sortDate is (null)
2015-03-08 12:06:00.503 WheredMyMoneyGo[5374:7322757] The sortDate is (null)
2015-03-08 12:06:00.503 WheredMyMoneyGo[5374:7322757] The sortDate is (null)

众所周知,我会做一些愚蠢的事情,但我一直在寻找这个 2 天没有成功。

有什么想法吗?

【问题讨论】:

【参考方案1】:

这里的问题是,您获取的结果控制器中的每个 section 都不是日期对象,因为您在这里处理它:

for (NSDate *headerDate in [transactionFRC sections])

相反,[transactionFRC sections] 实际上返回了一个 id<NSFetchedResultsSectionInfo> 对象数组。这些包含对象列表、对象计数和名称。在您的情况下,每个部分的名称将是字符串形式的日期。要对此进行测试,请将您的 viewDidLoad 代码替换为以下内容:

for (id<NSFetchedResultsSectionInfo> section in [transactionFRC sections])

    NSLog(@"The sortDate is %@", section.name);

但是,此日期的格式不是您想要的样式。你真的有两个选择:

    使用您的 dateFormatter 首先将部分的​​名称(字符串)转换为 NSDate 对象,然后将该日期对象重新格式化为所需格式的字符串。

    titleForHeaderInSection: 中获取相关部分中的第一个对象(如果该部分中有对象),并将其排序日期格式化为字符串并使用它。这是一个例子:

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    
        static NSDateFormatter *formatter = nil;
        if (!formatter) 
            formatter = [[NSDateFormatter alloc] init];
            [formatter setDateStyle:NSDateFormatterFullStyle];
            [formatter setTimeStyle:NSDateFormatterShortStyle];
        
    
        id<NSFetchedResultsSectionInfo> sectionInfo = transactionFRC.sections[section];
        WMMGTransaction *transaction = [sectionInfo.objects firstObject];
    
        NSString *sectionLabel = [formatter stringFromDate:transaction.sortDate];
    
        NSLog(@"The sortDate is %@", transaction.sortDate);
        NSLog(@"The sectionLabel is %@",sectionLabel);
    
        return sectionLabel;
    
    

我在 Xcode 中无法对其进行测试,但我已键入此内容,但希望它能让您有所收获。

【讨论】:

谢谢,我刚收到您的答复,很快就会实施。我很困惑地认为 [transactionFRC 部分] 返回了一个由任何对象存储为属性的数组。我会尽快在这里报告您的建议。 非常感谢,詹姆斯!很清楚的解释。它现在起作用了,你给了我一个关键的教训。我使用了你的第二种方法,顺便说一句,逐字记录。答案被接受并投票赞成。再次感谢!!!

以上是关于从 NSDate 获取 UITableView 标题的主要内容,如果未能解决你的问题,请参考以下文章

如何从 UIImage 获取 NSDATE?

如何从 NSDate 获取小时和分钟?

如何从 NSDate 获取当前日期、时间、年份?

iOS:从 NSDate 获取本地化小时

从NSDate和NSCalendar获取分钟小时秒

如何在 [NSDate 日期] 当天 00:00 获取 NSDate?