简体   繁体   English

将核心数据属性从NSString更改为NSDate,并使用日期选择器使此功能正常工作

[英]Changing Core Data Attribute from NSString to NSDate and getting this functionality to work using a Date Picker

I am working through my first app and need some advice on how to approach this next task and issue. 我正在通过第一个应用程序进行工作,并且需要一些有关如何处理下一个任务和问题的建议。 The premise of the app is the user has a table view, clicks on a plus button in the navigation bar and is presented with text fields to insert information. 该应用程序的前提是用户具有表格视图,单击导航栏中的加号按钮,并显示文本字段以插入信息。 Upon clicking on save, that gets saved to the core data and displayed in the table view. 单击保存后,该内容将保存到核心数据中并显示在表格视图中。

The table view is sectioned. 表格视图已剖开。 Right now, I have the "date" being represented as a NSString, just to get my app off the ground, but I need to change this to a DatePicker. 现在,我将“日期”表示为NSString,只是为了使我的应用程序起步,但是我需要将其更改为DatePicker。 The sections' are based on the Dates. 这些部分基于日期。

I have a Core Data Model as follows: 我有一个核心数据模型,如下所示:

  • Transaction Entity 交易实体
  • Person Entity 人实体
  • Occasion Entity 场合实体
  • Date Entity 日期实体

The Transaction Entity has a relationship to each of the other entities here. 交易实体与此处的每个其他实体都有关系。

As mentioned, at first, to get my app working and off the ground, I made the Date Entity have a dateOfEvent attribute which was a NSString rather than a NSDate but of course that will not work in the long run. 如前所述,首先,为了使我的应用程序正常运行,我使Date实体具有dateOfEvent属性,该属性是NSString而不是NSDate,但是从长远来看当然不起作用。

I have changed my model to NSDate for this attribute and regenerated the NSManagedObject Subclasses. 我已将此属性的模型更改为NSDate,并重新生成了NSManagedObject子类。

Independently, I have a DatePicker working without any issues but it outputs the information to a String in a textfield. 独立地,我有一个DatePicker,没有任何问题,但它将信息输出到文本字段中的String。

What I want to achieve now is to use the DatePicker, select a date and have that saved to the Core Data Date Entity (dateOfEvent attribute) which I can then use in the table view as the section titles. 我现在想要实现的是使用DatePicker,选择一个日期并将其保存到Core Data Date实体(dateOfEvent属性)中,然后我可以在表格视图中将其用作部分标题。

Here is my code for saving in the view controller: 这是我保存在视图控制器中的代码:

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    Date *enteredDate = (Date *)[Date occasionWithDate:self.dateTextField.text inManagedObjectContext:context];
    transaction.dates = enteredDate;
    // Code to save Person, Occasion, etc. 
}

The enteredDate is calling a specific occasionWithDate method: enterDate会调用特定的caseWithDate方法:

+ (Date *)occasionWithDate:(NSString *)enteredDate inManagedObjectContext:(NSManagedObjectContext *)context
    Date *date = nil;
    // Creating a fetch request to check whether the name of the person 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 person 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;
}

This does a fetchRequest to ensure I am either returning an existing date or adding a new one if that does not exist. 这会执行fetchRequest以确保我返回的是现有日期,或者如果不存在则添加一个新日期。

That is the behaviour I would like here, but of course, that method is passing a String and I need to pass a date. 这就是我在这里想要的行为,但是,当然,该方法正在传递字符串,并且我需要传递日期。

With this in mind, how do I go about selecting the value of the DatePicker, adding it to the Core Data database in the same way as above (checking whether the date exists) and having this displayed in the sections of the Table View? 考虑到这一点,我该如何选择DatePicker的值,以与上述相同的方式将其添加到Core Data数据库(检查日期是否存在),并将其显示在Table View的各个部分中?

The reason I want to check if the date exists is because if there is an event on the 2nd December 2013, it'll be unique. 我要检查日期是否存在的原因是,如果2013年12月2日有活动,它将是唯一的。 However if I create another event on the 2nd December 2013, I'd want it to use the existing 2nd December, rather than create a second entry for 2nd December. 但是,如果我在2013年12月2日创建另一个活动,我希望它使用现有的12月2日,而不是在12月2日创建第二个条目。 The reason is my app has a tab view where the second tab is predicated by dates and so I would not want two separate 2nd December there. 原因是我的应用程序具有选项卡视图,其中第二个选项卡以日期为基础,因此我不希望在那里有两个单独的12月2日。

This is a side note. 这是一个旁注。 The main thing I would like to achieve is, use the Date Picker and save the selected value to Transaction.dates.dateOfEvent to Core Data. 我要实现的主要事情是,使用日期选择器并将所选值保存到Transaction.dates.dateOfEvent到Core Data。

I know if I were to do something like date.dateOfEvent = [NSDate date] ; 我知道是否要执行类似date.dateOfEvent = [NSDate date] it would be assigning the date and time now. 它会现在分配日期和时间。 That is not what I want here. 那不是我想要的。

Any assistance would be massively appreciated. 任何帮助将不胜感激。

Thanks, 谢谢,

EDIT: Adding in UIDatePicker Code - this first code snippet below is for saving to the textField when using NSString as the attribute 编辑:添加UIDatePicker代码-下面的第一个代码片段用于在使用NSString作为属性时保存到textField

In viewDidLoad viewDidLoad

    [self.datePicker addTarget:self action:@selector(getSelection:) forControlEvents:UIControlEventValueChanged];

-(void)getSelection:(id)sender
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterLongStyle];
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];

    NSDate *date = [self.datePicker date];

    NSString *formattedDateString = [dateFormatter stringFromDate:date];
    self.dateTextField.text = formattedDateString;
}

Edit: The save to core data method is above - it calls occasionWithDate method and checks if the date exists already when the dateOfEvent attribute is NSString. 编辑:保存到核心数据方法在上面-当dateOfEvent属性为NSString时,它将调用ceventWithDate方法并检查日期是否已经存在。 Because I need to sort by ascending dates in the table view, I have changed the dateOfEvent to be a NSDate format 因为我需要在表格视图中按升序对日期进行排序,所以我将dateOfEvent更改为NSDate格式

To get the current date and time, I'm putting this code in the save method: 为了获取当前日期和时间,我将以下代码放入save方法中:

Date *date = [NSEntityDescription insertNewObjectForEntityForName:@"Date" inManagedObjectContext:context];

date.dateOfEvent = [NSDate date];
transaction.dates = date; 

That is giving me the current date and time. 那就是我当前的日期和时间。 What I want is for the user to select a date using the UIDatePicker and whatever date is selected, for that to be saved as the dateOfEvent attribute of the Date entity which I can then use in the Sections of the Table view. 我想要的是让用户使用UIDatePicker选择日期,并选择任何日期,然后将其保存为Date实体的dateOfEvent属性,然后可以在Table视图的Sections中使用。

To get NSDate from your UIDatePicker object use UIDatePicket date property. 要从您的UIDatePicker对象获取NSDate ,请使用UIDatePicket date属性。

date 日期

The date displayed by the date picker. 日期选择器显示的日期。

@property(nonatomic, retain) NSDate *date

Discussion The default is the date when the UIDatePicker object is created. 讨论默认值为创建UIDatePicker对象的日期。 The date is ignored in the mode UIDatePickerModeCountDownTimer; 该日期在UIDatePickerModeCountDownTimer模式下被忽略; for that mode, the date picker starts at 0:00. 对于该模式,日期选择器从0:00开始。 Setting this property does not animate the date picker by spinning the wheels to the new date and time; 设置此属性不会通过将轮子旋转到新的日期和时间来为日期选择器设置动画。 to do that you must use the setDate:animated: method. 为此,必须使用setDate:animated:方法。

check Apple UIDatePicker documentation 查看Apple UIDatePicker文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM