我开发了一个使用Core Data的应用程序。在一个UITableView中,我想显示我的实体列表,按照对象的保存日期排序。当我这样做时:
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"date"
cacheName:nil];
我为每个对象获取一个新部分,因为此代码也会根据秒数对日期进行分组。但我想要一个按日期分组的对象列表,但只根据日,月和年。有可能吗?怎么样?
非常感谢你的帮助!! ;)
答案 0 :(得分:41)
这应该适合你:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *rawDateStr = [[[self.fetchedResultsController sections] objectAtIndex:section] name];
// Convert rawDateStr string to NSDate...
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZ"];
NSDate *date = [formatter dateFromString:rawDateStr];
// Convert NSDate to format we want...
[formatter setDateFormat:@"d MMMM yyyy"];
NSString *formattedDateStr = [formatter stringFromDate:date];
return formattedDateStr;
}
<强> [编辑] 强>
Jus看到了你的评论以及你想要实现的目标,你可以创建一个瞬态NSDate
属性(非持久性),其格式与上面的代码类似(即没有H:mm:ss ZZZZ)并将该属性用作sectionNameKeyPath
值。
简而言之,对于具有foo
和fooDate
属性的fooDateTransient
对象,您会:
获取foo.fooDate
属性
使用上面的代码(或类似代码)对其进行转换,并将NSDate
结果分配给foo.fooDateTransient
创建fooDateTransient
对象时,使用sectionNameKeyPath
作为fetchedResultsController
。
答案 1 :(得分:23)
它适用于月份和年份,但它很容易使它适用于日,月和年。
答案 2 :(得分:2)
以下是Swift 3解决方案,按日期排序,但部分标题与个别日期相对应。
daySectionIdentifier
的瞬态属性。NSManagedObject
子类。删除可能在daySectionIdentifier
生成的Entity+CoreDataProperties.swift
的属性。到Entity+CoreDataClass.swift
文件,为daySectionIdentifier
添加以下getter:
// Transient property for grouping a table into sections based
// on day of entity's date. Allows an NSFetchedResultsController
// to sort by date, but also display the day as the section title.
// - Constructs a string of format "YYYYMMDD", where YYYY is the year,
// MM is the month, and DD is the day (all integers).
public var daySectionIdentifier: String? {
let currentCalendar = Calendar.current
self.willAccessValue(forKey: "daySectionIdentifier")
var sectionIdentifier = ""
if let date = self.date as? Date {
let day = currentCalendar.component(.day, from: date)
let month = currentCalendar.component(.month, from: date)
let year = currentCalendar.component(.year, from: date)
// Construct integer from year, month, day. Convert to string.
sectionIdentifier = "\(year * 10000 + month * 100 + day)"
}
self.didAccessValue(forKey: "daySectionIdentifier")
return sectionIdentfier
}
在UITableViewController
实施中,添加以下方法:
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
var sectionTitle: String?
if let sectionIdentifier = fetchedResultsController.sections?[section].name {
if let numericSection = Int(sectionIdentifier) {
// Parse the numericSection into its year/month/day components.
let year = numericSection / 10000
let month = (numericSection / 100) % 100
let day = numericSection % 100
// Reconstruct the date from these components.
var components = DateComponents()
components.calendar = Calendar.current
components.day = day
components.month = month
components.year = year
// Set the section title with this date
if let date = components.date {
sectionTitle = DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .none)
}
}
}
return sectionTitle
}
NSFetchedResultsController
时,请使用"daySectionIdentifier"
作为sectionNameKeyPath
参数调用初始值设定项。NSFetchedResultsController
排序描述符设置为您实体的普通旧"date"
属性。重要的是,基于"date"
的排序顺序将与基于我们刚刚构建的部分标识符的排序顺序一致。现在,您应该将表格视图按日分组(例如,&#34; 2017年2月6日和#34;),并按细粒度日期排序。
答案 3 :(得分:-1)
我认为这会更好。
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// Replace DataClassObject with whatever object your using
DataClassObject *tempObject = [[sectionInfo objects] objectAtIndex:0];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"d MMMM yyyy"];
NSString *formattedDateStr = [formatter stringFromDate:tempObject.date];
[dateFormatter release]
return formattedDateStr;
}
答案 4 :(得分:-1)
当遇到同样的问题时,我使用了@ BoltClock的Unicorn和@Rog的anwser。 只需将一个瞬态NSString * sectionTitle添加到我的托管对象,使用@“sectionTitle”作为sectionNameKeyPath并创建一个自定义getter,如下所示:
-(NSString *)sectionTitle
{
NSDate *_now = [NSDate date];
NSDate *_today = [_now dateByAddingTimeInterval: -86400.0];
NSDate *_yesterday = [_now dateByAddingTimeInterval: -172800.0];
NSDate *_thisWeek = [_now dateByAddingTimeInterval: -604800.0];
NSDate *_lastWeek = [_now dateByAddingTimeInterval: -1209600.0];
NSDate *_thisMonth = [_now dateByAddingTimeInterval: -2629743.0];
// if better precision required use something more sophisticated for month...
double today = [_today timeIntervalSince1970];
double yesterday = [_yesterday timeIntervalSince1970];
double thisWeek = [_thisWeek timeIntervalSince1970];
double lastWeek = [_lastWeek timeIntervalSince1970];
double thisMonth = [_thisMonth timeIntervalSince1970];
[self willAccessValueForKey:@"timestamp"];
double ts = [self.timestamp timeIntervalSince1970];
[self didAccessValueForKey:@"timestamp"];
NSString *title = @"";
if(ts >= today) title = NSLocalizedString(@"TODAY",nil);
else if (ts >= yesterday) title = NSLocalizedString(@"YESTERDAY",nil);
else if (ts >= thisWeek) title = NSLocalizedString(@"THIS WEEK",nil);
else if (ts >= lastWeek) title = NSLocalizedString(@"LAST WEEK",nil);
else if (ts >= thisMonth) title = NSLocalizedString(@"THIS MONTH",nil);
return title;
}