Getting the Row for Section indexPath in a tableView - ios

Recently I put implemented an indexing feature for the user names in my app. I have been trying to access the rows in each section and add them to my recipients array when the user taps the index path. I have tried passing many different values in my objectAtIndex: method but none seem to be working. I am able to log the correct index row and section in indexPathForRow:inSection: method but the return value is an indexPath and not an integer. So something with my objectForIndex: method is obviously not right. Any help or references would be super. cheers!
This line:
PFUser *user = [self.friends objectAtIndex:indexPath.section];
Returns only the first username in each section, no matter what name I tap in the section. So I need to access the Row in addition, not just the section.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
int section = indexPath.section;
int row = indexPath.row;
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
NSLog(#"newIndexPath: %#", newIndexPath);
PFUser *user = [self.friends objectAtIndex:indexPath.section];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user.objectId];
NSLog(#"added:%#",user);
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user.objectId];
NSLog(#"removed:%#",user);
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
}];
}

Hi this is enough try and let me know if you face any issues...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
NSArray * nameArray = [self.sectionsArray objectAtIndex:indexPath.section];
PFUser *user = (PFUser*)[nameArray objectAtIndex:indexPath.row];
// PFUser *user = (PFUser*)[self.friends objectAtIndex:indexPath.section];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user.objectId];
NSLog(#"added:%#",user);
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user.objectId];
NSLog(#"removed:%#",user);
}
// this is enough
}

Just like the code Spynet suggested only a little bit different:
NSArray *array = [self.sectionsArray objectAtIndex:indexPath.section];
PFUser *user = [array objectAtIndex:indexPath.row];
Using that code I was able to get the proper indexPath for row in each section. Also, in order to get the cells accessory checkmarks to work correctly I had to create a newIndexPath using the section and row values for each index. My final code is here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int row = indexPath.row;
int section = indexPath.section;
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
NSLog(#"newIndexPath: %#", newIndexPath);
[self.tableView deselectRowAtIndexPath:newIndexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:newIndexPath];
NSLog(#"sectionsArray:%#",self.sectionsArray);
NSArray *array = [self.sectionsArray objectAtIndex:indexPath.section];
PFUser *user = [array objectAtIndex:indexPath.row];
NSLog(#"array:%#",array);
NSLog(#"user:%#",user);
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user];
NSLog(#"recipients:%#",self.recipients);
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user];
NSLog(#"recipients:%#",self.recipients);
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
}];
}

Related

Checkmarks not working in a tableview

In my iOS app, I have a tableView and when you click on the cell, a checkmark shows up. When you click on the cell again though, the checkmark doesn't do away. I have checked my code over and over again. These are the two methods that have to do with UITableViewAccessoryCheckmark:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
cell.textLabel.text = user.username;
if ([self isFriend:user]) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
PFRelation *friendsRelation = [self.currentUser relationforKey:#"friendsRelation"];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
if ([self isFriend:user]) {
cell.accessoryType = UITableViewCellAccessoryNone;
for(PFUser *friend in self.friends) {
if ([friend.objectId isEqualToString:user.objectId]) {
[self.friends removeObject:friend];
break;
}
}
[friendsRelation removeObject:user];
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.friends addObject:user];
[friendsRelation addObject:user];
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
Can someone please post the correct code? Thank you!
Try setting the accessory view property on UITableViewCell to nil.
cell.accessoryView = nil;

Search and Checkmarks in tableViews

I am trying to make a search bar in iOS and have made it to where it filters results and then when you click on it, it shows a checkmark. When I delete the search text, the check mark goes away and the full page of cells appears but the cell that I selected in the search is not selected with a check mark. Can someone please fix the code below to help me?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableSet *selectedUsers = [NSMutableSet set];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user;
if (self.userResults != nil)
{
user = [self.userResults objectAtIndex:indexPath.row];
}
else
{
user = [self.allUsers objectAtIndex:indexPath.row];
}
cell.textLabel.text = user.username;
if ([selectedUsers containsObject:user])
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
if ([selectedUsers containsObject:user])
{
// user already selected
}
else
{
// select user
[selectedUsers addObject:user];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
PFRelation *friendsRelation = [self.currentUser relationforKey:#"friendsRelation"];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
[friendsRelation addObject:user];
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
} }];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
NSMutableSet *selectedUsers = [NSMutableSet set];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user;
if (self.userResults != nil)
{
user = [self.userResults objectAtIndex:indexPath.row];
}
else
{
user = [self.allUsers objectAtIndex:indexPath.row];
}
cell.textLabel.text = user.username;
if ([selectedUsers containsObject:user])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
PFRelation *friendsRelation = [self.currentUser relationforKey:#"friendsRelation"];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
[friendsRelation addObject:user];
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
} }];
PFUser *user1;
if (self.userResults != nil)
{
user1 = [self.userResults objectAtIndex:indexPath.row];
}
else
{
user1 = [self.allUsers objectAtIndex:indexPath.row];
}
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedUsers removeObject:user1];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedUsers addObject:user1];
}
}
See if this helps.
The thing is that when you close the search bar the table view is reloaded.this time you have to record all the cells index path that user select.That is you do it in didSelectRowAtIndexPath delegate Method,and save in an array value that user select.
and in cellForRowAtIndexPath you can check all the cell whose indexPath in in the array.
Hope you got it...
NSMutableArray *array=[[NSMutableArray alloc]init];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if
([selectedBillsArray containsObject:indexPath]) {
cell.accessoryType=UITableViewCellAccessoryCheckmark; }
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell= [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType==UITableViewCellAccessoryCheckmark)
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
[selectedBillsArray removeObject:[NSString stringWithFormat:#"%i",indexPath];
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedBillsArray addObject:[NSString stringWithFormat:#"%i",indexPath];
}
}
Do something like this...

didSelectRowAtIndexPath selecting multiple tableView cell accessory's

I have a tableView containing a list of user names that are indexed into sections and rows alphabetically. When I tap on one of the rows in a section, the correct user is added to my recipients array and a checkmark is places in the cell besides their name.. but a checkmark is also displayed next to other usernames that have not been selected and are not in the recipients array. I have tried to reassign the selected cell with a new indexPath (see code below) but have not been able to get it to work. It registers the correct path, but won't assign it. I am using a similar method for assigning the users the the rows in each section with no trouble but for some reason the accessory marks are giving me problems. I've seen some other threads on overflow about this same topic but wash;'t able to come to a solution for my case. any clues? cheers!
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int row = indexPath.row;
int section = indexPath.section;
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
[tableView deselectRowAtIndexPath:newIndexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:newIndexPath];
NSArray *array = [self.sectionsArray objectAtIndex:indexPath.section];
PFUser *user = [array objectAtIndex:indexPath.row];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user];
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
}];
and here's the cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Get the user names from the array associated with the section index in the sections array.
NSArray *userNamesInSection = (self.sectionsArray)[indexPath.section];
// Configure the cell with user name.
UserNameWrapper *userName = userNamesInSection[indexPath.row];
cell.textLabel.text = userName.user;
return cell;
}
As I see you made 2 mistakes in CellForRowAtIndexPath that did not check if cell is null to create one and set accessoryType for cell according to the recipient list.
You should do like below:
NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
PFUser *user = [self getUserAtIndexPath:indexPath];
cell.textLabel.text = user.name;
if ([self.recipients containObject:user]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;

TableViewCell checkmarks not disappearing when tapped?

Here is my method in my delegate:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
PFRelation *friendsRelation = [self.currentUser relationforKey:#"friendsRelation"];
if ([self isFriend:user]) {
cell.accessoryType = UITableViewCellAccessoryNone;
for (PFUser *friend in self.friends) {
if ([friend.objectId isEqualToString:user.objectId]) {
[self.friends removeObject:friend];
break;
}
}
[friendsRelation removeObject:user];
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.friends addObject:user];
[friendsRelation addObject:user];
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog (#"Error %# %#", error, [error userInfo]);
}
}];
}
When I run the app, everything works just fine with no errors or warnings but when I tap on friends to remove the checkmark by their name it does not happen.
This code syntax might help you check that it's working. Then you'll probably see as Matthias said that the issue is coming from your isFriend: method because your code looks fine for me.
Or another way, I think it's cleaner to separate the two logics of selecting/deselecting, so don't forget to enable the "multiple selection" on the tableview :
self.tableView.allowsMultipleSelection = YES;
And on the tableview delegate :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
Then to retrieve all selected items :
- (void)handleSelectedItems
{
NSArray *selectedItemIndexPaths = [self.tableView indexPathsForSelectedRows];
for (NSIndexPath *indexPath in selectedItemIndexPaths) {
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
// do what you want
// ...
}
}

iOS: Tableview multiple selection - AccessoryCheckmark checking reusable cells

I'm using a tableview with sections and multiple selection, but I have an issue with multiple rows being checked when one row is chosen...
I've seen a few other threads about this, but didn't really get a solution...
Here's my code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) indexPath
{
[employeeTable deselectRowAtIndexPath:[employeeTable indexPathForSelectedRow] animated:NO];
UITableViewCell *cell = [employeeTable cellForRowAtIndexPath:indexPath];
// get the letter in each section
NSString *alphabet = [charIndex objectAtIndex:indexPath.section];
// get the names beginning with the letter
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *names = [listOfNames filteredArrayUsingPredicate:predicate];
NSString *name = [names objectAtIndex:indexPath.row];
for(int i = 0; i < [employeeConnection.employees count]; i++)
{
Employee *aEmployee = [employeeConnection.employees objectAtIndex:i];
NSString *firstName = aEmployee.firstName;
NSString *lastName = aEmployee.lastName;
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
if([fullName isEqualToString:name])
{
NSLog(#"Name: %#", name);
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// Reflect selection in data model
[chosenEmployees addObject:aEmployee.employeeID];
[chosenEmployeesNames addObject:name];
} else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
// Reflect deselection in data model
[chosenEmployees removeObject:aEmployee.employeeID];
[chosenEmployeesNames removeObject:name];
}
}
}
}
Update: Added cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.textLabel.textColor = [UIColor whiteColor];
}
// Get the letter in the current section
NSString *alphabet = [charIndex objectAtIndex:[indexPath section]];
// Get the names beginning with the letter
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *names = [listOfNames filteredArrayUsingPredicate:predicate];
if([names count] > 0)
{
// Extract the name
cell.textLabel.text = [names objectAtIndex:indexPath.row];
}
return cell;
}
I would suggest storing an NSMutableSet of either the checked ManagedObject (when using CoreData) or simply the checked IndexPaths. In -cellForRowAtIndexPath: you can then check if the cell is supposed to be checked.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *const identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
cell.textLabel.textColor = UIColor.whiteColor;
}
if ([self.checkedIndexPaths containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *const cell = [tableView cellForRowAtIndexPath:indexPath];
[table deselectRowAtIndexPath:indexPath animated:NO];
if ([self.checkedIndexPaths containsObject:indexPath]) {
[self.checkedIndexPaths removeObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else {
[self.checkedIndexPaths addObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
Since cells are being reused, you need to set the accessory mark to on or off for every cell in the table in the cellForRowAtInexPath table datasource method.
So the cell.accessoryType cell property should be soecified in the cellForRowAtInexPath and not the didSelectRow delegate method.
In the didSelectRow, just keep track of the selected rows in an array, and set the cells accessory mark to none or checkmark in the cellForRowAtInexPath dependingon the array value.

Resources