【发布时间】:2014-04-14 16:31:21
【问题描述】:
我有一个UITabBarController 有两个选项卡(时间轴和日期);两者都是UITableViewControllers。用户通过点击UINavigationBar 按钮将信息添加到这些表格视图中,然后填写名称、事件、金额和日期等信息。前三个是UITextFields,日期是UIDatePicker。将信息保存到 Core-Data 后,UITableViewController 将使用 NSFetchedResultsControllers 进行更新。
CoreData 的模型是一个与 Years 实体有关系的事务实体。我还有一个 Years Entity 用于检查其他地方的日期(但不仅仅是年份)。
第二个选项卡是一个“日期”选项卡,它只过滤从日期开始的年份,因此如果用户有 5 个 2014 年条目,它只会显示 2014 一次,然后当用户单击 2014 单元格时,他们将看到年份 = 2014 的所有条目。这同样适用于其他年份。
问题
我在英国地区,但我在其上编写应用程序的 Mac 在美国地区,我刚刚注意到一个大问题。
如果您在 devie 上将时区更改为新加坡或亚洲(时间上在英国之前的某个地方),日期选项卡将与您留下的相同。但是,如果您通过电话将其更改为纽约、墨西哥或加拿大(基本上在英国之后的任何时间),那么“日期”选项卡就会变得混乱,每年都会下降一个。
我的意思是,如果您在“日期”选项卡中有 2014、2013、2012 并且您在英国地区,如果您转到纽约时区并进入应用程序,它现在会显示 2013, 2012 年和 2011 年。
发生了什么事?
这是添加条目的“保存”方法中的一些代码:
NSCalendar *yearCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *yearComponent = [yearCal components:NSYearCalendarUnit fromDate:self.datePicker.date];
[yearComponent setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDate *selectedYear = [yearCal dateFromComponents:yearComponent];
// Calling the year category to check whether it exists.
Years *years = (Years *)[Years matchingYear:selectedYear inManagedObjectContext:context];
transaction.years = years;
这调用了年份Entity的类别:
+ (Years *)matchingYear:(NSDate *)enteredYear inManagedObjectContext:(NSManagedObjectContext *)context
{
Years *years = nil;
// Creating a fetch request to check whether the year already exists, calling from the Add/DetailViewController.
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Years"];
request.predicate = [NSPredicate predicateWithFormat:@"yearOfEvent = %@", enteredYear];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"yearOfEvent" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *matchedYears = [context executeFetchRequest:request error:&error];
if (!matchedYears)
{
// No errors to handle
}
else if (![matchedYears count])
{
// If the year count is 0 then create it
years = [NSEntityDescription insertNewObjectForEntityForName:@"Years" inManagedObjectContext:context];
years.yearOfEvent = enteredYear;
}
else
{
// If the year exists, return it.
years = [matchedYears lastObject];
}
return years;
}
我的 UIDatePicker 设置为当前日期,因此用户无法选择未来的日期。
这是日期选项卡的 fetchResultsController 代码:
- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Years" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSPredicate *d = [NSPredicate predicateWithFormat:@"transactions.years.@count !=0"];
[fetchRequest setPredicate:d];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"yearOfEvent" 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;
}
在我的 Save 方法中,我注意到我将时区设置为 UTC,我这样做的原因是因为如果我没有这样做,当我去另一个国家并更改我的时区时,它会添加“2014”日期选项卡中 2014 年的每个条目显然是错误的。但这当然会在这里引起一些问题。
要求
我只需要能够保持“日期”选项卡不变,无论我在哪个时区。
要点
格式保存为年份等原因有几个原因,并且无法更改,因为它会影响整个应用程序。 UIDatePicker 在 Storyboard 中设置为英国语言环境,这有几个原因。但是,即使将语言环境设置为“默认”,也会出现同样的问题。美国和加拿大的时区删除了一年,因此“日期”选项卡中的 2014 变为 2013,2013 变为 2012,2012 变为 2011。这对我来说没有意义。
任何关于这方面的指导将不胜感激!
【问题讨论】:
-
你应该保存 NSDate 而不是 D、M、Y...
-
感谢@Larme - 将其保存为该格式而不是 NSDate 有几个原因,但我不确定这是否是导致问题的原因,因为它适用于除美国和加拿大以外的每个时区..你对此有什么想法吗?
-
@Tom Harrington 解释了为什么它“更好”。另外,您可以轻松使用
NSPredicate并检查年份,使用NSDateComponents创建日期,如果这可能会吓到您。
标签: ios core-data nsfetchedresultscontroller uidatepicker