1

解决方案!!

感谢乔希的耐心:D

因此,初始问题中的代码始终勾选所选单元格并取消选择先前选择的单元格,而不将任何内容保存到NSUserDefaults. 在 Josh 的大量帮助之后,新代码(右下方)如下(与他的回复中完全相同/我只对其进行了一点清理并删除了之前尝试使其工作中定义的 @properties)。

用户点击 7 个单元格之一。然后将被点击单元格的 indexPath 保存在 中NSUserdefaults,当再次打开 TableView 时,会在先前点击的单元格旁边显示一个复选标记。indexpath 始终保存在同一个目录中,NSObject因此只会显示一个复选标记。

#import "CycleTableViewController.h"
#import "SettingsTableViewController.h"

@interface CycleTableViewController ()
@property (nonatomic) int selectedRow;
@end

@implementation CycleTableViewController
@synthesize array;

- (void)viewDidLoad {
    //load array containing options
    array=@[@"1", @"2",  @"3", @"4", @"5", @"6", @"7"];

    [super viewDidLoad];
    }

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

- (void) viewWillDisappear:(BOOL)animated{
    //save indexpath of tapped cell to NSUserdefaults
    [[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"cycle"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    }

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
    }

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [array count];
    }

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

    cell.textLabel.text = [array objectAtIndex:indexPath.row];
   
    //display checkmark next to the tapped cell
    if(indexPath.row == self.selectedRow){
       cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
    else{
       ell.accessoryType = UITableViewCellAccessoryNone;
        }         
        return cell;
    }

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //assign indexpath to selectedRow, so NSUserdefaults can save them
    self.selectedRow = indexPath.row;        
    [self.tableView reloadData];
    }

    //save indexpath of tapped cell to NSUserdefaults
    [[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"cycle"];
    [[NSUserDefaults standardUserDefaults] synchronize];

@end


最初的问题

我一直在阅读大量关于将索引路径保存到用户默认值的帖子,但没有一个对我有用......

在下面的 TableView 中,我有一个数据数组 (1-7),一旦按下单元格,就会显示并传递给另一个 ViewController。按下的单元格有一个复选标记,如果我使用导航控制器返回,我可以看到复选标记。一次只选择一项。如果我按另一行,复选标记会更改。

所以现在我想将所选行的索引路径保存到 UserDefaults (在 中didselectrowat indexpath)并将其加载到viewdidload但我总是得到一个build failed,无论我尝试什么......

有人可以指出我正确的方向吗?这应该很容易,但我不知何故无法让它工作:/

更新代码!一旦我得到它的工作,我会上传完成的答案!

#import "CycleTableViewController.h"
#import "SettingsTableViewController.h"


@interface CycleTableViewController (){
    NSString *currentCategory; // pointer to the currently checked item
}
// other @property declarations here or in your .m file
#define CHECKED_KEY @"kCheckedBoxKey"

@property (nonatomic) int selectedRow;



@end

@implementation CycleTableViewController
@synthesize array;



- (void)viewDidLoad {
    
    //load tickmark according to newCell;
    
    array=@[@"21+7", @"22+6",  @"23+5", @"24+4", @"25+3", @"26+2", @"28"];

    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void) viewWillAppear:(BOOL)animated {
    self.selectedRow = [[[NSUserDefaults standardUserDefaults] objectForKey:@"cycle"] intValue];
    
 }

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [array count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIndentifier=@"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIndentifier forIndexPath:indexPath];
    
    cell.textLabel.text = [array objectAtIndex:indexPath.row];
    
    return cell;

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    [[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"cycle"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    NSIndexPath *IndexPath = [NSIndexPath indexPathForRow:self.selectedRow inSection:0];
    UITableViewCell *Cell = [tableView cellForRowAtIndexPath:IndexPath];
    Cell.accessoryType = UITableViewCellAccessoryCheckmark;
    
}

@end

4

2 回答 2

0

您在代码中的哪个位置保存用户默认值?

didSelectRowAtIndexPath中,您可以添加:

[[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"nameOfSetting"];
[[NSUserDefaults standardUserDefaults] synchronize];

cellForRowAtIndexPath您可以检查是否

indexPath.row == [[[NSUserDefaults standardUserDefaults] objectForKey:@"nameOfSetting"] intValue]

如果是这样,请添加复选标记附件。如果不是,则不显示任何附件。

请注意,我实际上会创建一个包含 selectedValue 的属性,并且只有在离开设置页面或点击保存按钮时,您才会真正更新用户默认值。然后在viewWillAppear我将此属性设置为等于用户默认值中的设置并在表上调用重新加载。

编辑 要扩展最后的注释,您可以执行以下操作:

在界面...

@property (nonatomic) int selectedRow;

在实施中...

self.selectedRow = [[NSUserDefaults standardUserDefaults] objectForKey:@"nameOfsetting"] intValue];

只要在头文件中声明了 selectedRow 属性,您就可以将此代码放在viewWillAppearviewDidAppear甚至是您要从中分离的上一个视图控制器中。prepareForSegue我不会把这段代码放在viewDidLoad.

然后分别在cellForRowAtIndexPath我会添加类似的东西:

if(indexPath.row == self.selectedRow){
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
    cell.accessoryType = UITableViewCellAccessoryNone;
}

编辑#2

OptionsViewController显示当前设置的位置,您可以从 standardUserDefaults 加载设置。您可以像我提到的那样保存一个数字作为设置(即,如果您有设置选项,您可以将它们编号为 0 - 6 并使用 typedef 使代码更清晰),或者您可以存储一个字符串。如果您将设置存储为数字,则只需要字典将数字映射到设置描述。如果您将设置存储为字符串,则可以只显示该字符串。

无论选择哪种方法,在OptionsViewController执行此操作时:

#import "SettingsViewController.h"

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
   if([segue.destinationViewController isKindOfClass:[SettingsViewController class]]){
       SettingsViewController *settingsViewController = (SettingsViewController *) segue.destinationViewController;
       settingsViewController.selectedSetting= <INSERT YOUR SETTING FROM STANDARDUSERDEFAULTS>
    }
 }

基本上,您将您的设置从选项传递到包含您的表格的设置视图。您可以像上面那样selectedSettingSettingsViewController数字或字符串中输入。同样,您必须将设置转换为数字,以便表格知道哪一行有复选标记。我会保持其余代码相同,即cellForRowAtIndexPath. 您需要以某种方式检查 indexPath.row 是否与 selectedSetting 匹配(即,如果它是字符串,则需要将其转换为数字)。并在viewWillAppearviewDidAppear重新加载 tableView 以便显示复选标记。

当用户选择不同的行时,您可以更新 selectedSetting 属性,然后在viewWillDisappearprepareForSegue(即在展开 segue 之前)您可以更新 standardUserDefaults。

于 2015-01-06T00:02:33.543 回答
0
#import "CycleTableViewController.h"
#import "SettingsTableViewController.h"


@interface CycleTableViewController (){
    NSString *currentCategory; // pointer to the currently checked item
}
// other @property declarations here or in your .m file
#define CHECKED_KEY @"kCheckedBoxKey"

@property (nonatomic) int selectedRow;

@end

@implementation CycleTableViewController
@synthesize array;

- (void)viewDidLoad {

    //load tickmark according to newCell;

    array=@[@"21+7", @"22+6",  @"23+5", @"24+4", @"25+3", @"26+2", @"28"];

    [super viewDidLoad];
}

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

- (void) viewWillAppear:(BOOL)animated {
    self.selectedRow = [[[NSUserDefaults standardUserDefaults] objectForKey:@"cycle"] intValue];        
 }

- (void) viewWillDisappear:(BOOL)animated{
    [[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"cycle"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [array count];
}

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

    cell.textLabel.text = [array objectAtIndex:indexPath.row];

    if(indexPath.row == self.selectedRow){
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
     }
    else{
        cell.accessoryType = UITableViewCellAccessoryNone;
    }         
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     self.selectedRow = indexPath.row;        
     [self.tableView reloadData];
}

@end
于 2015-01-07T00:13:29.777 回答