ios - 使用核心数据在 NSDate 属性中仅按年份过滤 TableView Controller

标签 ios objective-c core-data nsdate nsfetchedresultscontroller

我有一个我确信可以实现的要求,但我只是不知道如何实现它,我们将不胜感激。

我有一个简单的带有两个选项卡的 TableView Controller 。用户按下导航栏上的加号按钮,然后以模态方式转到另一个 View Controller 以添加新事务。用户将文本添加到文本字段并从 UIDatePicker 中选择一个日期。用户按下保存,这将保存到核心数据,并按时间顺序显示在第一个选项卡 TableView 中,日期构成部分。

第二个选项卡应该只显示单元格中交易的年份。所以这里没有部分,而是一个 TableView ,只显示条目存在的年份,如 2013、2012、2011 等。例如,如果您创建了 20 个条目,年份为 2013,那么 2013 应该在此日期表中显示一次 View ,当您单击 2013 时,您会看到所有这些条目,等等。如果您没有任何 2012 年的条目,那么您将不会看到它。

我被困在如何实现这个日期 TableView 上。

我正在使用 NSFetchedResultsController,因此使用 fetchRequests 和谓词,这应该是可以实现的。

应用程序的模型是: 交易实体 场合实体 日期实体 人实体

交易实体与场合、人物和日期实体有关系。

让我们看一些代码:

模态视图 Controller 中的保存方法:

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    Item *itemType = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:context];

    Person *enteredPerson = (Person *)[Person personWithName:self.nameTextField.text inManagedObjectContext:context];
    transaction.whoBy = enteredPerson;

    Occasion *enteredOccasion = (Occasion *)[Occasion occasionWithTitle:self.occasionTextField.text inManagedObjectContext:context];
    transaction.occasion = enteredOccasion;

    Date *date = (Date *)[Date occasionWithDate:self.datePicker.date inManagedObjectContext:context];
    transaction.dates = date;

}

Date 对象使用 occasionWithDate 方法调用 Date NSManagedObject 子类上的一个类别来检查现有日期是否已经存在。我认为重复的功能还没有起作用,但问题在下面。调用的方法是:

+ (Date *)occasionWithDate:(NSDate *)enteredDate inManagedObjectContext:(NSManagedObjectContext *)context
{
    Date *date = nil;
    // Creating a fetch request to check whether the date already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Date"];
    request.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent = %@", enteredDate];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dateOfEvent" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *dates = [context executeFetchRequest:request error:&error];
    if (!dates)
    {
        // Handle Error
    }
    else if (![dates count])
    {
        // If the dates count is 0 then let's create it
        date = [NSEntityDescription insertNewObjectForEntityForName:@"Date" inManagedObjectContext:context];
        date.dateOfEvent = enteredDate;
    }
    else
    {
        // If the object exists, just return the last object .
        date = [dates lastObject];
    }
    return date;
}

dateOfEvent 属性是 NSDate 类型。我正在使用以下方法确保第一个表格 View 中的部分标题格式正确:

-(NSString *)sectionDateFormatter
{
    return [NSDateFormatter localizedStringFromDate:self.dates.dateOfEvent
                                          dateStyle:NSDateFormatterLongStyle
                                          timeStyle:NSDateFormatterNoStyle];
}

我的问题是:如何在 DateTableView 中使用 NSPredicate 来表示只显示年份信息,然后使用 cellForRow 为每年创建一个单元格

这必须分为两部分;我需要确保 Date Table View 没有任何重复的条目,例如 2013 年的多个单元格,并确保 DateTable View 只显示年份等。

我怀疑我可能不得不像这个问题一样使用 NSDateComponents Core Data Predicate Date Comparison但我真的很抱歉,我是新手,老实说我不知道​​如何解决这个问题。

我的日期 NSFetchedReusltsController 是这样的:

- (NSFetchedResultsController *)fetchedResultsController
{
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];

    if (_fetchedResultsController != nil)
    {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Date" inManagedObjectContext:managedObjectContext];
    fetchRequest.entity = entity;

// EDIT: Code Predicate added from Answer

NSDate *theDate = self.date.dateOfEvent;

NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [currentCalendar components:NSYearCalendarUnit fromDate:theDate];

NSInteger year = components.year;


NSDate *startDate = [currentCalendar dateFromComponents:components];
components.year++;

NSDate *endDate = [currentCalendar dateFromComponents:components];

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent >= %@ AND dateOfEvent < %@", startDate, endDate];


    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"dateOfEvent" ascending:NO];
    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
    fetchRequest.fetchBatchSize = 20;
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;
}

任何帮助将不胜感激 - 我只是不知道如何实现这一点!

最佳答案

NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [currentCalendar components:NSYearCalendarUnit fromDate:[NSDate date]];
components.year = 2012;

NSDate *startDate = [currentCalendar dateFromComponents:components];
components.year++;

NSDate *endDate = [currentCalendar dateFromComponents:components];

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent >= %@ AND dateOfEvent < %@", startDate, endDate];

关于ios - 使用核心数据在 NSDate 属性中仅按年份过滤 TableView Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20349008/

相关文章:

ios - 使用 iOS 退格字符

ios - 如何从输入日期开始计算准确的完成天数

iphone - 以编程方式为单个 UITableViewCell 设置高度?

ios - 嵌套核心数据获取

ios - 如何清空整个核心数据表?

ios - 无法将 parentContext 添加到 NSManagedObjectContext,上下文已经有一个协调器

ios - 不同的请求有不同的 DispatchQueue

如果全新的应用程序,iOS 应用程序更新代码冲突?

objective-c - 帮助制作自动更新程序

objective-c - 在 UIViewController 的 viewDidUnload 中释放 IBOutlets?