NSUserDefaults没有首次亮相

时间:2014-07-24 13:46:26

标签: objective-c cocoa nsuserdefaults

所以我在过去的几个月里一直在学习iOS,并且最近遇到了这个问题。登录过程中我的应用程序中有一个设置屏幕,应该保存一些与用户有关的基本信息。问题是当视图首次出现在标签栏控制器中时,静态分组表视图为空白,而没有可用于cell.detailLabel.text的信息。我使用NSLog发现,当从键中检索对象时,它们是空的。但是,当我选择一个单元格来更改它的信息并按下另一个视图控制器时,我可以返回并且所有值将从保存到NSUser默认值的先前输入中显示。我很好奇为什么会发生这种情况并找到解决方案。感谢

#import "SettingsController.h"
#import <Parse/Parse.h>
#import "LogInViewController.h"
#import "AddSettings.h"
#import "AddUrination.h"
#import "ChooseAlarmController.h"

@interface SettingsController ()



@end

@implementation SettingsController
- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addUrination=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addUrinationView:)];
    self.navigationItem.rightBarButtonItem=addUrination;

    /*Rename the back button which every pushed on controller will have*/
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = backButton;

    NSLog(@"view loaded");

}


-(void)viewWillAppear:(BOOL)animated
{
    /*Everytime view appears, we want to repopulate the table with updated content*/
    NSLog(@"Settings View appeared,Load the keys");
    /*Load every cell with appropiate details*/
    NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
    NSIndexPath *path=[NSIndexPath indexPathForRow:0 inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
    cell.detailTextLabel.text=[defaults objectForKey:@"FirstNameKey"];
    NSLog(@"%@",cell.detailTextLabel.text);
    path=[NSIndexPath indexPathForRow:1 inSection:0];
    cell=[self.tableView cellForRowAtIndexPath:path];
    cell.detailTextLabel.text=[defaults objectForKey:@"LastNameKey"];
    path=[NSIndexPath indexPathForRow:2 inSection:1];
    cell=[self.tableView cellForRowAtIndexPath:path];
    cell.detailTextLabel.text=[defaults objectForKey:@"NumberOfUrinationsKey"];
    [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
    path=[NSIndexPath indexPathForRow:0 inSection:1];
    cell=[self.tableView cellForRowAtIndexPath:path];
    cell.detailTextLabel.text=[defaults objectForKey:@"StartingAlarmKey"];
    path=[NSIndexPath indexPathForRow:1 inSection:1];
    cell=[self.tableView cellForRowAtIndexPath:path];
    cell.detailTextLabel.text=[defaults objectForKey:@"FinalAlarmKey"];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(IBAction)addUrinationView:(id)sender
{
    [self performSegueWithIdentifier:@"AddUrinationSegue" sender:self];
}




- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // If Log Out Button is selected
    if(indexPath.row==0 && indexPath.section==2){
        NSLog(@"Log Out selected");
        [PFUser logOut];
        UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Are You Sure?" message:@"If you would like to change your mind, press cancel. Otherwise choose log out" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Log Out", nil];
        [alert show];
    }
    NSLog(@"Selected row is %ld %ld", (long)indexPath.section,(long)indexPath.row);
    /*Segue depends on which cell is selected. First section segues to text input (AddSettings.h)*/
    if((indexPath.section==0 && indexPath.row<2) || (indexPath.section==1 && indexPath.row==2)){
        [self performSegueWithIdentifier:@"AddSettingSegue" sender:self];
    }
    /*Choose alarm controller is selected*/
    if(indexPath.section==1 && indexPath.row<2){
        [self performSegueWithIdentifier:@"AddAlarmSegue" sender:self];
    }
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    if([segue.identifier isEqualToString:@"AddSettingSegue"]){
        AddSettings *settingsController=[segue destinationViewController];
        /*index path contains both the section and row of the selected cell*/
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSLog(@"Section:%ld Row:%ld",(long)indexPath.section,(long)indexPath.row);
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        settingsController.titleOfController=cell.textLabel.text;
    }

    if([segue.identifier isEqualToString:@"AddUrinationSegue"])
    {
        AddUrination *addUrinationView=[segue destinationViewController];
    }
    if([segue.identifier isEqualToString:@"AddAlarmSegue"]){
        ChooseAlarmController *alarm=[segue destinationViewController];
        NSIndexPath *indexPath=[self.tableView indexPathForSelectedRow];
        UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
        alarm.titleOfController=cell.textLabel.text;
    }
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex==1){
        [self performSegueWithIdentifier:@"UnwindToLogIn" sender:self];
    }

}
@end

1 个答案:

答案 0 :(得分:0)

[super viewWillAppear:animated]添加到viewWillAppear:覆盖的顶部。根据{{​​3}},

“如果您覆盖此方法,则必须在您的实施中的某个时刻调用super。”

虽然您的应用程序通常不会崩溃或任何内容(如果省略),但除非您调用[super viewWillAppear:animated],否则不会发生基类执行的重要初始化,这可能会导致意外行为,例如标签值未显示在您的表中查看单元格。

作为最佳做法,除非您明确不希望发生默认行为(例如覆盖touchesBegan:withEvent:,否则每当覆盖Apple的某个方法时,始终应调用super方法。 )。虽然有例外,但是通常被覆盖的初始化方法(如viewDidLoadviewWillAppear:)应该在方法的开头调用它们的超级方法,而被覆盖的拆除方法(如viewWillDisappear:)应该调用它们的超级方法。端。