I have a simple UITableViewController
with some static cells in the UITableView
. The UITableView
is being populated by another UITableViewController
's prepareForSegue
. There are two sections to this UITableViewController
, where the first section is a NSMutableArray
of strings and the second section is a NSMutableArray
containing a .txt file with strings. Some "languages" will only have one section and others will have two. There's nothing else fancy about the UITableView
. With the use of this tutorial: http://www.appcoda.com/swipeable-uitableviewcell-tutorial/#disqus_thread, I have managed to implement custom gestures on the cell, so I can swipe the cell to mark it as favourite. I had to implement the use of the code in that tutorial to change the default behaviour from Delete to Star, as can be seen in the screenshot below:
Once a user has selected the star image, I want there to be UIImage on the cell itself, representing that this cell has been starred.
Here's some code, starting with the cellForRowAtIndexPath
static NSString *strCellIdentifier = @"CustomLeafletVideoCell";
CustomLeafletVideoTableViewCell *customCell = (CustomLeafletVideoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:strCellIdentifier];
self.rightUtilityButton = [NSMutableArray new];
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"])
{
[self.rightUtilityButton sw_addUtilityButtonWithColor:
[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]
icon:[UIImage imageNamed:@"Favorites@2x.png"]];
}
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"])
{
[self.rightUtilityButton sw_addUtilityButtonWithColor:
[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]
icon:[UIImage imageNamed:@"Database@2x.png"]];
}
customCell.rightUtilityButtons = self.rightUtilityButton;
customCell.delegate = self;
When the user taps the image in the cell, this method fires off:
- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index
{
switch (index) {
case 0:
{
self.selectedRowCollection = [[NSMutableDictionary alloc] init];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
CustomLeafletVideoTableViewCell *cell = (CustomLeafletVideoTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
// We create a new NSString and assign it to the custom label's text (which is obtained from the cellForRow method)
NSString *cellTitle = cell.customCellLabel.text;
NSLog(@"The text is %@", cellTitle);
NSManagedObjectContext *context = [self managedObjectContext];
Favourites *favourites = [NSEntityDescription insertNewObjectForEntityForName:@"Favourites" inManagedObjectContext:context];
favourites.title = cellTitle;
NSError *error = nil;
if (![context save:&error])
{
// Error
}
[cell hideUtilityButtonsAnimated:YES];
[self.tableView reloadData];
}
}
I am storing the "title" in Core Data.
Issue
When I swipe the cell and press the star image, it doesn't load up the cell with the UIImageView
in the designated area. The reason it doesn't is because I truly don't understand what to do.
I understand the answer is indicating that I should create a custom class and while I understand the theory behind that, I cannot understand how to actually implement this appropriately.
I've looked at this reference: Using BOOL objects in NSMutableArray to determine cell statuses to use a checkmark as the accessory when a cell is selected. This works, but it places a checkmark in the first section and second section on the same corresponding cell.
I've figured out I can get the exact row number and section number from indexPath.row
and indexPath.section
, but I'm just not sure how to tackle this information at all. I could always add a isFavourite
BOOL
to the Core Data
Model, but how do I actually set that in the cellForRowAtIndexPath?
So to conclude, and for the 250 bounty I'm putting on this question, I need to understand how:
- Set the specific
indexPath.row
andindexPath.section
with the image, and - Maintain it so that every time I come back to this
UITableViewController
, the star is on the appropriate cell
I'm kind of a newbie here, so if you're happy to help with as much information as you can, I'd really appreciate that.
Also, I'm not having issues with what to do with the Favourite after; that works - I just need to get the image onto the cell when a cell has been marked as favourite.
Any guidance would be appreciated.
Update
This is the code I have for setting the favourites:
self.isFavourite = @(!self.isFavourite.boolValue);
Where self.isFavourite
is a NSNumber
property created on this UITableViewController
.
In the cellForRowAtIndexPath
:
customCell.customCellLabel.text = [NSString stringWithFormat:@"%@",[self.availableLeaflets objectAtIndex:indexPath.row]];
if (self.isFavourite.boolValue)
{
customCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
customCell.accessoryType = UITableViewCellAccessoryNone;
}
The code here is setting the titles from the self.availableLeaflets
. This works to set the checkmark on the cell, but the problem is, when I come back to this UITableViewController
, the checkmark hasn't persisted on the selected cell.
Here, self.availableLeaflets
is a NSMutableArray
that gets populated and set from the prepareForSegue
in the previous UITableViewController
.
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:
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
.