Xcode using NSUserDefaults to save data on Master

2019-09-06 19:24发布

问题:

I am creating a master detail app for the ipad that should save whatever the user is typing (using buttons on the popover view which puts some text on the label in that popover view) in the table view cel in master view controller.

So basically I have a popover view that contains a UILabel called inputDisplayLabel and whatever button the user presses that buttons text goes in that UILabel. When enter button is pressed it adds that text to the tableviews cel. Now I want to save whatever is in that table view sothat when I quit the application and start over again the text still stays in the tableview cel.

I tried to add a button called SaveValue and coded it lik so:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.inputDisplayLabel.text forKey:@"savedValue"];
[defaults synchronize];

now I tried loading it with adding another button called loadValue with the following code:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.tableView = [defaults objectForKey:@"SavedValue"];

but it doesnt work. Where do I actually put the loading code so that it is there when the application starts so that I dont have to use another button.

I hope someone can help me. Thanks.

Edited:

-(void)setTheTextOfLabelWith:(NSString *)str
{
    text = str;
    if (!_objects) {
        _objects = [[NSMutableArray alloc] init];
    }
    //[_objects insertObject:[NSDate date] atIndex:0];
    [_objects insertObject:[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];


    [self.inputViewPopover dismissPopoverAnimated:YES];
}

回答1:

Objective C is case sensitive "savedValue" is different to "SavedValue". And of course the tableview can't directly take a string. You have to assign the string/text to e.g. a label in a tableviewcell. Put the code in viewDidLoad, so set the label's text there, if it is in a tableViewCell you will have to set it in "cellForRowAtIndexPath" method. Maybe should take a look at the viewcontroller lifecycle and the UITableViewDelegate and DataSource protocols.

// edit: I don't think so.. basically you have a dynamic tableview and want multiple cells displaying some text you saved in user defaults? To have a dynamic tableview, you normally implement the UITableViewDataSource and UITableViewDelegate protocols in your ViewController, which displays/manages the tableview. There you create the cells using the "cellForRowAtIndexPath" method from the UITableViewDataSource protocol. As you want to save more than one entry you could use an array to save everything in user defaults and just iterate it in cellForRow.. to get all the texts in the cells.

E.g.

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.yourArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *theCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(theCell == nil)
    {
        theCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                         reuseIdentifier:CellIdentifier];
    }

    theCell.textLabel.text = [self.yourArray objectAtIndex:indexPath.row];

    return theCell;
}

If you want to save really a lot of data, think about CoreData or some kind of XML to save the data, as the user defaults are commonly rather used to save some kind of settings (but for just some "texts" it should totally work out).

// edit2: After checking out your project, I noticed that you tried to save the labels in NSUserDefaults, which is not possible. You have to save the texts of these labels and then restore the labels with these texts after loading them from NSUserDefaults. The easiest solution (or at least the one without many modifications) is to modify your load and save methods like so:

- (IBAction)load
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSArray *texts = [defaults objectForKey:@"items"];
    for(NSString *currentText in texts)
    {
        [self setTheTextOfLabelWith:currentText];
    }
}

- (void)savingData
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSMutableArray *textToSave = [[NSMutableArray alloc] init];
    for(UILabel *currentLabel in _objects)
    {
        [textToSave addObject:currentLabel.text];
    }

    [defaults setObject:textToSave forKey:@"items"]; 
    [defaults synchronize];
}

You can also find that solution as a reply to your mail.