My Controller inherits from UITableViewController - but this delegate method is not found? - objective-c

Background - I'm trying to make my controller deselect a row when its selected and tapped
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell isSelected]) {
// Deselect manually.
[tableView.delegate tableView:tableView willDeselectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[tableView.delegate tableView:tableView didDeselectRowAtIndexPath:indexPath];
self.selectedRow = -1;
[tableView beginUpdates];
[tableView setTableHeaderView:self.headerView];
[tableView endUpdates];
} else {
self.selectedRow = indexPath.row;
[tableView beginUpdates];
[tableView setTableHeaderView:nil];
[tableView endUpdates];
}
return indexPath;
}
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
return [super tableView:tableView willDeselectRowAtIndexPath:indexPath];
}
When the code executes and a row is tapped while selected:
tableView:willDeselectRowAtIndexPath:]: unrecognized selector sent to instance 0xbf59e00
My Controller inherits from UITableViewController. Its set as the delegate on the tableView. What am I missing?

You can check this link
How to deselect a selected UITableView cell?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Change the selected background view of the cell.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Related

Show and Hide a Custom Cell

My UITableView has one section, and if all cells are visible there will be a total of 6.
There is only one cell that I would like to be able to show and hide.
Here's an overview:
cell 0 - always shown
cell 1 - always shown
cell 2- always shown
cell 3 - always shown
cell 4 - initially hidden / will show or hide if cell 3 is tapped
cell 5 - always shown
Here's a sample of what I have tried for animating/showing the cell through didSelectRowAtIndexPath. Not sure if I am on the right track, but if someone could take a look and help me see where I have messed up I would greatly appreciate it!
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == 3)
{
if (self.indexPathSelected != indexPath)
{
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.indexPathSelected.row+1 inSection:self.indexPathSelected.section]].hidden = YES;
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
[tableView beginUpdates];
[[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section]] performSelector:#selector(setHidden:) withObject:NO afterDelay:0.25];
self.indexPathSelected = indexPath;
[tableView endUpdates];
return;
}
}
}
So when I tap on cell 3, it just makes the last cell flicker.
By considering, there will be of total 6 rows in tableview and only one section, for this better u make a mutable array to hold all the objects for ur tableview then use insertRowsAtIndexPaths: withRowAnimation: and deleteRowsAtIndexPaths: withRowAnimation: instead of using selector following code gives the example how to hide and show the tableview cell
mutArray = [[NSMutableArray alloc]initWithObjects:#"cell 1",#"cell 2",#"cell 3",#"cell 4",#"cell 6", nil]; //initially ur array contains only 5 objects notice that "cell 5" is not there this will be hidden
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [mutArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.aTableView dequeueReusableCellWithIdentifier:#"cell"];
if(mutArray.count != 6) //initially only 5 rows are present
{
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = [mutArray objectAtIndex:indexPath.row];
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
}
else //for 5th row it must be a custom cell
{
return [mutArray objectAtIndex:indexPath.row];//becz u are already initilised ur custom cell just return it
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(indexPath.row == 3)
{
int totalRows = [tableView numberOfRowsInSection:indexPath.section];
[tableView beginUpdates];
if(totalRows == 5)
{
//initilise ur custom cell and add it to datasource array
CustomCell *customCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"customCell"];
customCell.textLabel.text = #"cell 5";
[mutArray insertObject:customCell atIndex:4];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[mutArray removeObjectAtIndex:5];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationFade];
}
[tableView endUpdates];
}
}
if all ur cells are custom then dont need to comepare in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
Hope this helps u :)

How to tell which UITableCells are selected with a check mark in a Multi Select UITableview. Objective C

I have a UITableview and in that TableView I which populates with json data. I have implemented a multi selected tableview code that checks the touched table cell with a checkmark.
My question is how can I tell which of my tableview cells I have selected and how do I put an action to the selected table view cells?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.json2.count;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = self.json2[indexPath.row][#"SurveyName"];
//cell.detailTextLabel.text = self.json1[indexPath.row][#"AssetDesc"];
// Sets the accessory for the cell
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
if (thisCell.accessoryType == UITableViewCellAccessoryNone) {
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
thisCell.accessoryType = UITableViewCellAccessoryNone;
}
}
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
//add your own code to set the cell accesory type.
return UITableViewCellAccessoryNone;
}
So normally If I were to make a segue from a tableview cell I would do the following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Perform segue
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self performSegueWithIdentifier: #"showSurveyForm" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showSurveyForm"]) {
// NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
CameraViewController *destViewController = segue.destinationViewController;
// Hide bottom tab bar in the detail view
destViewController.hidesBottomBarWhenPushed = YES;
destViewController.surveyQuestionId = self.surveyQuestionIDParsed;
destViewController.jsonTitleforSurvey = self.json2;
destViewController.surveyTitleAssetId = self.assetSurvey;
NSLog(#"Survey ID for Survey: %#", self.surveyQuestionIDParsed);
NSLog(#"Survey name titile: %#", self.json2 );
NSLog(#"Asset ID for Title: %#", self.assetSurvey);
}
else if ([segue.identifier isEqualToString:#"showCameraRoll"]) {
// NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// Hide bottom tab bar in the detail view
}
else if ([segue.identifier isEqualToString:#"showJsonData"]) {
// NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
}
else if ([segue.identifier isEqualToString:#"testPickerDemo"]) {
// NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
}
}
I would like to make a segue after choosing the multi selected cells in my UItableview.
e.g I make a selection and 2 rows are checked. I would like to capture or see in my nslog which tableview cells were selected so I can do another json call and segue based on the rows that were selected.
I know how to call and parse json and make a segue.
You can modify your -didSelectRowAtIndexPath something like this :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *selStr = [yourSourceArray objectAtIndex:indexPath.row];
---> NSMutableArray *selArray = [[NSMutableArray alloc] init]; //Write this line in viewDidLoad method.
if (thisCell.accessoryType == UITableViewCellAccessoryNone)
{
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
[selArray addObject:selStr];
}
else
{
thisCell.accessoryType = UITableViewCellAccessoryNone;
[selArray removeObject:selStr];
}
NSLog(#"selArray :: %#",selArray);
}
UPDATE :
It will give you the Array of textLabel's text of Selected Rows. Then you can use it in -yourButtonPressed method
- (IBAction)yourButtonPressed:(id)sender;
{
NSLog(#"selArray :: %#",selArray);
}
GoodLuck !!!

Delete a cell row in Objective-C

Want to delete a row when you swipe with your finger on the cell.
I got this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Delete");
}
After running the Delete button appears but when I press on it nothing happens. What do I need to insert in to the brackets?
And my .m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *str = cell.textLabel.text;
NSLog(#"U selected %#", str);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.dataSourceArray removeObjectAtIndex:indexPath.row];//or something similar to this based on your data source array structure
//remove the corresponding object from your data source array before this or else you will get a crash
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.array = #[#"test",#"test"];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:nil action:#selector(updateArray) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
}
Try this,
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.array removeObjectAtIndex:indexPath.row];//or something similar to this based on your data source array structure
//remove the corresponding object from your data source array before this or else you will get a crash
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}

How to add a checkmark in a UITableViewCell

Say I have a small tableview(no scroll) and when a user taps an option, it changes some setting in the app. I used this function:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//some code here
}
Now I want to use UITableViewCellAccessoryCheckmark for the option that is selected, I mean it should display a checkmark in the cell the user selected (and remove checkmark from previously selected option). How do I do that?
How about
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
for (UITableViewCell *cell in [tableView visibleCells]) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Just use the accessoryTypeproperty of a UITableViewCell.
#property(nonatomic) UITableViewCellAccessoryType accessoryType
Like this:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//code for reusing or init a new cell goes here
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

indexPathForSelectedRow always returns 0,0 irrespective of the row selected

I would like to replace the cell that is touched by a custom cell. I do this by calling reloadRowsAtIndexPaths
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Row selected: %d", [tableView indexPathForSelectedRow] row]);
NSLog(#"Section selected: %d", [tableView indexPathForSelectedRow] section]);
//return a custom cell for the row selected
}
When I try to access/log the indexPathForSelectedRow from within the cellForRowAtIndexPath, it returns 0,0 no matter which cell I select. Why is this?
Your call to reloadRowsAtIndexPaths: will cause the table view to reload the given cells and therefore cause the table to no longer have a selected row at that position. The cellforRowAtIndexPath method is a request from the data source to provide a row for the given index path. If you need to determine if a cell was selected prior to the request, you could store the indexPath of the selected row in a member. Then check the member in your cellForIndexPathMethod.
The following code sample assumes you are using ARC for memory management.
- (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 = [NSString stringWithFormat:#"Cell %d_%d", indexPath.section, indexPath.row];
// Configure the cell...
if(selectedIndexPath != nil) {
NSLog(#"Selected section:%d row:%d", selectedIndexPath.section, selectedIndexPath.row);
//TODO:Provide a custom cell for the selected one.
//Set the selectedIndexPath to nil now that it has been handled
selectedIndexPath = nil;
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Store the selected indexPath
selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}