I have a simple UITableViewController
with some static cells in the UITableView
. The UITableView
is being populated by another U
Your code marks all cells as favorite when a user taps on the star in one cell because you store only 1 key in the UserDefaults.
You have to store the favorite state for each cell individually. Each cell must have its own 'favorite' boolean value.
Update:
This is a working example on how to achieve want you want without using Core Data. I simplified the example for clarity reasons:
Here's what you have to do:
#import "ViewController.h"
#import <CoreData/CoreData.h>
#import "CellData.h"
#import "AppDelegate.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic) UITableView *tableView;
@property (nonatomic) NSMutableDictionary *favoritesDict;
@property (nonatomic) NSInteger context;
@property (nonatomic) NSString *language;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// setup the table view
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
[self.view addSubview:self.tableView];
// setup the favorites dictionary in user defaults (if it does not exist)
if ([[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] == nil) {
[[NSUserDefaults standardUserDefaults] setObject:@{} forKey:@"favoritesDict"];
}
// set the language of your current table view
self.language = @"en";
// load favorites from user defaults
self.favoritesDict = [[[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] mutableCopy];
}
// this method changes the favorite state of the cell at a given index path
- (void)toggleFavoriteStateForCellAtIndexPath:(NSIndexPath *)indexPath {
// toggle the favorite state of the cell
NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];
if (self.favoritesDict[key] == nil) {
self.favoritesDict[key] = @(1);
} else {
[self.favoritesDict removeObjectForKey:key];
}
// save the change
[[NSUserDefaults standardUserDefaults] setObject:self.favoritesDict forKey:@"favoritesDict"];
// reload the cell
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
// add the text to your cell
// set up favorite state
NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];
if (self.favoritesDict[key]) {
// show the favorite image
cell.accessoryType = UITableViewCellAccessoryCheckmark; // for this example: show checkmark
} else {
// hide the favorite image
cell.accessoryType = UITableViewCellAccessoryNone; // for this example: hide checkmark
}
return cell;
}
#pragma mark - UITableViewDelegate
// toggle the favorite state of the cell when the user selects it
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self toggleFavoriteStateForCellAtIndexPath:indexPath];
}
@end
This example works for tables with multiple sections. It uses a NSDictionary and stores favorited cells in a key that has the following syntax LANGUAGE_SECTION_ROW
. To check if a cell is marked as favorite just check if there is a object for the related key in the dictionary. The actual value of that key does not matter. You just check for the key.
Just make sure that you set the language string in viewDidLoad
.