Show if tableview cell have been clicked before? - ios

I'm developing an app with a news feed.
This is a PFQueryTableView loading content from parse.com.
I also have a detail ViewController attached with a segue.
My question is:
How can I show that there is a cell that hasn't been clicked before?
Like in the Mail application in IOS.
Here's a picture:
http://i.stack.imgur.com/vO2N3.png
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Nyhet";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"Rubrik";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 10;
}
return self;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Change button color
sidebarButton.tintColor = [UIColor whiteColor];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
sidebarButton.target = self.revealViewController;
sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
/* if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}*/
[query orderByDescending:#"Prioritering"];
return query;
}
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
return cell;
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"Rubrik"];
recipe.prepTime = [object objectForKey:#"Text"];
recipe.detaljer = [object objectForKey:#"Detaljer"];
recipe.rubriker = [object objectForKey:#"Rubrik"];
destViewController.recipe = recipe;
}
}
#end

I think it's better use custom UITableViewCell example:
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property(assign) bool beforeClicked
#end
CustomTableViewCell.m
#import CustomTableViewCell.h
#implementation CustomTableViewCell
#synthesize beforeClicked;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
#end
And, example:
CustomTableViewCell.h //add this header
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = (CustomTableViewCell *)[[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
cell.beforeClicked = NO;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *myCell = [tableView cellForRowAtIndexPath:indexPath];
myCell.beforeClicked = YES;
}

Two solutions come to mind.
The simpler solution would be using an NSMutableArray to hold all visited cells. In didSelectRowAtIndexPath: do this :
if (![visitedCellsArray containsObject:[NSNumber numberWithInt:indexPath.row]])
[visitedCellsArray addObject:[NSNumber numberWithInt:indexPath.row]];
Then set a backgroundColor to your cell (just a suggestion, you may use any UI indicator - dot, color, etc) in your cellForRowAtIndexPath:
Second, might not be conducive to your purpose. I don't really know if the dictionary you are using is mutable or not, and whether adding keys will have any effect on your flow of control. But If adding a key is possible, add a key like #"seen" and set it with [NSNumber numberWithBool:YES] in didSelectRowAtIndexPath:, and in cellForRowAtIndexPath: add appropriate UI indication based on the value of this key. This method is better memory wise.

I'd give your PFReceipt objects a property BOOL new.
Then just get and set that property and in cellForRow you set the font based on the vale of the property.
clean and even persistent.
...
so to reiterate:
modify PFReceipt object to have a property new
modify - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
...
cell.clickedBefore = !receipe.new;
mark receipes as no longer new when shown
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
...
PFObject *object = [self.objects objectAtIndex:indexPath.row];
selectedCell.clickedBefore = !object.new;

None of the solutions provided take into account that there may be more than one user of the app. If you store a "read" or "new" property in the object, this will only show if ANYBODY has read it. So if Jane reads it, Mark will see it as read.
To handle this separately for all users, you need another parse class to handle reading status. This gets a little complex to implement, but it is the only way to solve it all on the server.
Another option would be to store a read status list on every client. This means some kind of local persistent store that knows what recipes are read, and compare this to the data fetched from Parse.

Related

stuck at 3rd level of hierarchal tableview data

I am developing app which is using storyboard and using two UITableView and one Label UIViewController. This app take data from the .plist file. I am able to retrieve data from .plsit show in first table and the according to the selected row data shown on second table but when I click to view the detail second table only one array strings I can view and can't view others. here is the sample for understating. A > AA > AAA and B > BB > BBB.
I have three topics in the first table i.e. Lumber Puncture, Urinary catheterization and veni puncture. Now when I click on each cell it displays me data in second UITableView according to the cell. Lets suppose showing me following data:
introduction
indication
equipments
etc
Now when I click the introduction of my Lumber puncture data it shows me detail of lumber puncture from the .plist array data. But if I click on the Urinary catheterization introduction on the second data cell, it also shows me the first Lumber puncture detail. So how can I solve this problem? kindly help me with your detail answers as I am new to develop iOS apps. Thanks
Here is some code for the first table and passing data to second table.
#implementation ViewController
{
NSArray *tableData;
NSArray *Components_Procedure;
}
#synthesize tableView1;
- (void)viewDidLoad
{
[super viewDidLoad];
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
tableData = [dict objectForKey:#"Procedure"];
Components_Procedure = [dict objectForKey:#"Component"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProcedureCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Procedure"]) {
NSIndexPath *indexPath = [self.tableView1 indexPathForSelectedRow];
Components *destViewController = segue.destinationViewController;
destViewController. componentArray= [Components_Procedure objectAtIndex:indexPath.row];
}
}
#end
Second table code and passing detail data to UIViewcontrollers UILables
#implementation Components
{
NSArray *detail;
}
#synthesize tableView2;
#synthesize componentArray;
- (void)viewDidLoad
{
[super viewDidLoad];
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
detail = [dict objectForKey:#"LumberPuncture"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [componentArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ComponentCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [componentArray objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Detail"]) {
NSIndexPath *indexPath = [self.tableView2 indexPathForSelectedRow];
DetailView *destViewController = segue.destinationViewController;
destViewController.headerName = [componentArray objectAtIndex:indexPath.row];
destViewController.contentName = [detail objectAtIndex:indexPath.row];
}
}
#end
and detail UIViewController class
#import "DetailView.h"
#implementation DetailView
#synthesize headerLabel;
#synthesize headerName;
#synthesize contentLabel;
#synthesize contentName;
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the Label text with the selected recipe
headerLabel.text = headerName;
contentLabel.text = contentName;
}
#end
You need to use both methods, in didSelectRowAtIndexPath you should call [self performSegueWithIdentifier:#"identifier" sender:self];
In the same View Controller you should have the prepareForSegue method grab the destinationViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath (NSIndexPath *)indexPath
{
self.someProperty = [self.someArray objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"segueID" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *vcToPushTo = segue.destinationViewController;
vcToPushTo.propertyToSet = self.someProperty;
}
Just add this method:
– tableView:didSelectRowAtIndexPath:
Typically, you use “didSelectRowAtIndexPath” method, which is invoked after user selects a row, to handle the row selection and this is where you add code to specify the action when the row is selected.
This and the "willSelectRowAtIndexPath" methods are used for row selection. The only difference is that “willSelectRowAtIndexPath” is called when a specified row is about to be selected. Usually you make use of this method to prevent selection of a particular cell from taking place.

custom cell not being displayed

So i created a custom cell (using the .xib file) and linked it using a custom controller class and I also didn't forget to write in the cell identifier. I also gave the same cell identifier in my table view controller prototype cell. In the custom cell controller class I just have an outlet to a text label in the .h file. Below is the code for my table view controller. When I run the app, the custom cells are not displayed but there are cells there because i can click on them (but they are just white). What am I doing wrong, why aren't the custom cells displaying?
If I use the default cells (not custom), then everything works fine. So the problem is that I'm not using my custom cells correctly somewhere.
#import "ListmaniaTableViewController.h"
#import "ListmaniaTableViewCell.h"
#interface ListmaniaTableViewController ()
#property (strong, nonatomic) NSMutableArray *tasks; //of task object
#end
#implementation ListmaniaTableViewController
- (void)viewDidLoad{
[super viewDidLoad];
task *task1 = [[task alloc] init];
task1.taskDescription = #"TASK 1";
[self.tasks addObject:task1];
task *task2 = [[task alloc] init];
task2.taskDescription = #"TASK 2";
[self.tasks addObject:task2];
task *task3 = [[task alloc] init];
task3.taskDescription = #"TASK 3";
[self.tasks addObject:task3];
}
- (NSMutableArray *)tasks{
if(!_tasks){
_tasks = [[NSMutableArray alloc] init];
}
return _tasks;
}
/*- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"Add New Item"]) {
}
}
- (void)addNewTask:(task *)newTask{
[self.tasks addObject:newTask];
}
#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.tasks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(ListmaniaTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
}
#end
But the
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
in viewDidLoad:.
The code you have in tableView:willDisplayCell:forRowAtIndexPath: method should be in tableView:cellForRowAtIndexPath: method. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
return cell;
}
I figured out the problem. I had an outlet in the custom cell that was doubly linked. I also moved the line below into viewdidload as suggested by #dasdom
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];

Getting the value of a clicked cell that has been loaded from parse?

I have a PFQueryTableViewController where I loaded certain information. I want to get the value of the cell you click to open another table with the information with the class name of the cell you clicked. I had tried a lot of ways but it doesn't work, I think that i am not taking the value of the label of the cell because the error says:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' setObjectForKey: object cannot be nil (key: classname)'
I am using this code:
- (id)initWithCoder:(NSCoder *)aCoder {
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Hospitales";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"Hospital";
// The title for this table in the Navigation Controller.
self.title = #"Hospitals";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 10;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"Location"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell
cell.textLabel.text = [object objectForKey:#"Hospital"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Location: %#", [object objectForKey:#"Location"]];
return cell;
}
-(void)tableView:(UITableView *)tableView CellAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
cell.textLabel.text = [_data objectAtIndex:indexPath.row];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"People" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check that a new transition has been requested to the DetailViewController and prepares for it
if ([segue.identifier isEqualToString:#"People"]){
//Get the selected data
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString* hospitalData = _data[indexPath.row];
[[segue destinationViewController]setHospital:hospitalData];
}
}
It's not so safe to rely on the UI to get the data you need, as a result you are violating the core MVC concept.
didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"People" sender:self];
}
prepareForSegue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"People"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}

How to select and save multiple values from tables rows

here i have made a table class in which i have a list of 120 words, now i have to select minimum ten rows of the table for further precision.. please any one can guide me that how can i select more than 10 rows from table and save these value in specific array or somewhere else.. please help me out of it.
#implementation tableview
NSArray *myArray ;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
myArray = [NSArray arrayWithObjects:
#"ad (a-d)",.......,Nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [myArray count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row]; //=#"ASDF" works.
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
#end
For multiple cell selection in your table add this code inside didSelectRowAtIndexPath: method. For saving selection values, create an iVar NSMutableArray and add the newly selected object inside didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
One quick idea that come into mind is, as soon as you select a row/cell, save the values in a collection object (array, dictionary), and keep on adding.
Delete from the collection if you deselect the row/cell.

Set an `UIImageView` to not highlighted on a custom UITableViewCell

I'm developing an iOS application with latest SDK.
I have a UITableView with a custom UITableViewCell:
#interface FavouriteCell : UITableViewCell
#property (unsafe_unretained, nonatomic) IBOutlet UIImageView *selectIcon;
#property (unsafe_unretained, nonatomic) IBOutlet UILabel *favName;
#property (nonatomic) BOOL checked;
+ (NSString *)reuseIdentifier;
#end
On selectIcon I set two images from normal and highlighted. When I do cell.checked = !selected; on tableView:didSelectRowAtIndexPath: it works perfectly.
But when I try to reset every selected cell on clearSelectedFavourites:, it doesn't work.
#interface FavViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate, UIAlertViewDelegate>
{
#private
NSMutableArray* _favsSelected;
BOOL* _isOnEditingMode;
}
// ######### FavViewController implementation ##############
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = NSLocalizedString(#"Favoritos", #"Favoritos");
self.tabBarItem.image = [UIImage imageNamed:#"fav"];
_favsSelected = [[NSMutableArray alloc] init];
_isOnEditingMode = NO;
}
return self;
}
- (UITableViewCell* )tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cellForRowAtIndexPath");
static NSString* CellIdentifier = #"FavCell";
FavouriteCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"FavouriteCell" owner:self options:nil];
cell = _favCell;
self.favCell = nil;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.favName.font = [UIFont systemFontOfSize:15.0f];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark - UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRowAtIndexPath: %#", indexPath);
if (tableView.isEditing)
{
BOOL selected = NO;
if ((_favsSelected != nil) && ([_favsSelected count] > 0))
selected = ([_favsSelected indexOfObject:indexPath] != NSNotFound);
FavouriteCell* cell =
(FavouriteCell*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(cell.checked ? #"Yes" : #"No");
cell.checked = !selected;
if (selected)
[_favsSelected removeObject:indexPath];
else
[_favsSelected addObject:indexPath];
}
}
- (IBAction)editFavList:(id)sender
{
NSLog(#"edit button clicked!");
if ([_favList isEditing])
{
[self clearSelectedFavourites];
[_favList setEditing:NO animated:YES];
[_editButton setImage:[UIImage imageNamed:#"ButtonEdit.png"] forState:UIControlStateNormal];
}
else
{
[_favList setEditing:YES animated:YES];
[_editButton setImage:[UIImage imageNamed:#"done_button.png"] forState:UIControlStateNormal];
}
}
- (void)clearSelectedFavourites
{
for(int index = 0; index < [_favsSelected count]; index++)
{
NSIndexPath* indexPath = (NSIndexPath*)[_favsSelected objectAtIndex:index];
FavouriteCell* cell = (FavouriteCell*)[self tableView:_favList cellForRowAtIndexPath:indexPath];
cell.checked = NO;
}
[_favsSelected removeAllObjects];
}
- (void)configureCell:(FavouriteCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = nil;
object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];
cell.favName.text = [[object valueForKey:#"name"] description];
}
Do you know why?
I have tried to set selectIcon to not hightlighted manually, but it doesn't work, and that code if the latest test I did.
I have also tested this: [cell setHighlighted:NO]; on clearSelectedFavourites: and it doesn't work.
You are not showing us your custom [self configureCell:cell atIndexPath:indexPath]; function, so I cannot know what's going on.
However a few things first:
The cells on the TableView are being reused.
So you cell select state needs to be set every time for each cell.
Also on your clearSelectedFavourites function, you are getting a reference to all selected cells, then clear their selection, which is pointless, because the cells are going to be reused.
You only need to loop through the visible UITableView cells and change their selection status, then clear your _favsSelected array...
- (void)clearSelectedFavourites
{
NSArray *cells = [self.tableView visibleCells];
for (FavouriteCell *cell in cells)
{
cell.checked = NO;
//might not be needed, or might be needed
[cell setNeedsDisplay];
}
[_favsSelected removeAllObjects];
}
Finally on your configureCell function, you should check if the cell should be checked or not, based on your _favsSelected array entries and just select it or not.
Edit
In your configureCell function you should check if the cell needs to be checked or not:
- (void)configureCell:(FavouriteCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = nil;
object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];
cell.favName.text = [[object valueForKey:#"name"] description];
cell.checked = [_favsSelected containsObject:indexPath];
}
You can do like this :
[tbl beginUpdates];
/* call you method with animation */
[tbl endUpdates];
[tbl reloadData];

Resources