Checkmark in a tableview, only one selected - ios

Hi I know how to add a tick mark on each row when you select it, but how can you only allow ONE to be ticked ?
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.CityTableView deselectRowAtIndexPath:indexPath animated:YES];
[self.CityTableView setTintColor:[UIColor grayColor]];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self.CityTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
this does it for every one, but I want it to remove the last one and add the new one when another one is pressed.
thanks

Create an instance variable as NSIndexPath *selectedIndex;
In your
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Your cell Initialization here
cell.accessoryType = [indexPath isEqual:selectedIndex] ?UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath * prevIndexPath = selectedIndex;
selectedIndex = indexPath;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:prevIndexPath, indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
}

Related

Selecting one UITableViewCell selects the other cell after scrolling

Even though it's common question but I'm not getting how to fix this.
I referred Selecting one UITableViewCell selects the other cells at that same position when you scroll up or down But i didn't understand.
I'm having allMumbaiArray (using in cellForRowAtIndexPath) and tableview alllMumbaiTableview. By using following code i can select and deselect the row.
UPDATED as per EI Captain's solution
#property (nonatomic, strong) NSMutableArray *arrIndexpaths;
tableView Methods -:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"CellIdentifier"];
}
cell.textLabel.text = [allMumbaiArray objectAtIndex:indexPath.row];
if ([self.arrIndexpaths containsObject:[NSNumber numberWithInt:indexPath.row]])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.view endEditing:YES];
NSString *testing =[allMumbaiArray objectAtIndex:indexPath.row];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.arrIndexpaths addObject:[NSNumber numberWithInt:indexPath.row]];
NSLog(#"%#",testing);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryType = UITableViewCellAccessoryNone;
[self.arrIndexpaths removeObject:[NSNumber numberWithInt:indexPath.row]];
}
Issue : 1) when i select first row after scrolling the tablewview another row get selected.How to Fix this?
2) After selecting and deselecting row continuously, how can i maintain the only selected row values ?
Here is the solution
make one mutable array that stores selected index of tableview cell..
#property (nonatomic, strong) NSMutableArray *arrIndexpaths;
cellForRowAtIndexPath
if ([self.arrIndexpaths containsObject:[NSNumber numberWithLong: indexPath.row]])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.arrIndexpaths addObject:[NSIndexSet indexSetWithIndex:indexPath.row]];
}
didDeselectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryType = UITableViewCellAccessoryNone;
[self.arrIndexpaths removeObject:[NSIndexSet indexSetWithIndex:indexPath.row]];
}
Here is the sample project...
demo project
If your cell are not showing accessory then you just need to reload them
[_ableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
try this in didSelectRowAtIndexPath and didDeselectRowAtIndexPath.

UITableView : select row with checkmark but no highlight

Issue: I only want to show the selected cells with checkmark. I don't want the grey highlight.
I tried:
cell.selectionStyle = UITableViewCellSelectionStyleNone
but didn't work.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
ProfileSelection *profile = [self.profileSelections objectAtIndex:indexPath.row];
cell.textLabel.text = [profile profileName];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.profileSelectionsTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
ProfileSelection *profile = [self.profileSelections objectAtIndex:indexPath.row];
self.mobileProfileId = [profile.profileId stringValue];
[_continueButton setEnabled:YES];
}
How about this:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
The selectionStyle property should be enough to remove the highlight.
If you want to show the checkmark after the used has selected the row, you need to implement the tableView:didSelectRowAtIndexPath: method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView cellForRowAtIndexPath:visibleIndexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
In Swift, the easiest way is to deselect a cell without animation right after it has been selected:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
}
delete your this function
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Try to use this your problem will be solved
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone
cell.textLabel.text = #"Checking Table View";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Go to Storyboard. Select your Table View Cell. Set Selection to None. Then add below codes:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
This thread looks a bit old, but I actually came across a decent solution for this recently. In case anyone stumbles across this thread, I figure I might as well post an answer. Especially since I spent hours trying to track this down.
I can't find my original sources anymore, but here's what I found out:
The highlight is made by a background view on the UITableViewCell on the selectedBackgroundView property. If we have a subclass of the table cell, we can detect the transition to the editing state with willTransitionToState: and set the background view to one that is clear/white instead of the blue/gray styles.
Here's what I ended up doing, and it works pretty well.
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
// To remove the blue/gray highlight on the table cell when selected,
// set the selection background to a clear view.
if (state & UITableViewCellStateShowingEditControlMask) {
// If we're moving to an edit state, set the custom background view.
UIView *bgView = [[UIView alloc] init];
[bgView setTintColor:[UIColor whiteColor]];
[bgView setBackgroundColor:[UIColor clearColor]];
[self setSelectedBackgroundView:bgView];
} else {
// Otherwise, just remove it completely.
// The system should handle the rest.
[self setSelectedBackgroundView:nil];
}
}
The plus side to this over the other solutions I've seen is that this one is quite minimal. No need for tracking instance variables or anything else.

store selected cells textLabel text in an array

How do i store all selected cells text label text in a NSMutableArray?
How do i remove the correct cells text from the NSMutableArray when a cell is deselected?
What i have this far:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([self.allSelectedUsers containsObject:indexPath]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"Yeeees");
}else{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
// Configure the cell
cell.textLabel.text = object[#"username"];
return cell;
}
This is when i'm selecting a cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([self.allSelectedUsers containsObject:indexPath]) {
[self.allSelectedUsers removeObject:indexPath];
}
else{
[self.allSelectedUsers addObject:indexPath];
}
NSLog(#"%d", self.allSelectedUsers);
[tableView reloadData];
}
When i check the log it doesn't display anything about the cells text label.
As I can't see how you're getting object instance, I suggest you to get back cell and read the title again.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Lazy initialise array
if (!self.allSelectedUsers) {
self.allSelectedUsers = [NSMutableArray new];
}
// Take action
if ([self.allSelectedUsers containsObject:indexPath]) {
[self.allSelectedUsers removeObject:indexPath];
} else {
[self.allSelectedUsers addObject:indexPath];
}
[tableView reloadData];
// Logging all selected users
for (NSIndexPath *sIndexPath in self.allSelectedUsers) {
NSLog(#"%#", [tableView cellForRowAtIndexPath:sIndexPath].textLabel.text);
}
}
You are currently storing NSIndexPath objects, not NSString objects, so it's not exactly what your question is asking. With your PFTableViewController, you have access to the selector objectAtIndexPath:.
for (NSIndexPath *indexPath in self.allSelectedUsers) {
NSLog(#"%#", [self objectAtIndexPath:indexPath][#"username"]);
}
Note: You shouldn't be calling reloadData in your didSelectRowAtIndexPath: responder; change the accessory type for the cell instead.
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
You should also implement didDeselectRowAtIndexPath: to know when a user deselects a row.

Multiple checkMark when row selected in UITableView IOS

I have a UITableView that displays checkmarks when a row is selected. The problem is that When i select a row in didSelectRowAtIndexPath and add a checkmark on the selected row it adds an additional checkmark. Here's my code
Any help would be very much appreciated.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text=[[Model.category objectAtIndex:indexPath.row] categoryName];
cell.imageView.image=[[Model.category objectAtIndex:indexPath.row]categoryImage];
//cell.detailTextLabel.text =#"Breve DescripciĆ³n de la categoria";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([self.tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark) {
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType =UITableViewCellAccessoryNone;
[self.cellSelected removeObject:indexPath];
}else {
[tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
[self.cellSelected addObject:indexPath];
}
[self checkMark];
[tableView reloadData];
}
- (void)checkMark{
for (NSIndexPath * indexPath in self.cellSelected) {
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
}
}
[self.tableView cellForRowAtIndexPath:indexPath] call in the didSelectRowAtIndexPath will not return the exact cell. It can be same cell, new cell or reused cell. If it is a reused cell at its accessory view has a checkmark, you will end up having two cells with checkmark.
Its better to store in the array and use it accordingly. If you are planning to have multiple selections, Use the code example below.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.cellSelected = [NSMutableArray array];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Cell Initialisation here
if ([self.cellSelected containsObject:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//if you want only one cell to be selected use a local NSIndexPath property instead of array. and use the code below
//self.selectedIndexPath = indexPath;
//the below code will allow multiple selection
if ([self.cellSelected containsObject:indexPath])
{
[self.cellSelected removeObject:indexPath];
}
else
{
[self.cellSelected addObject:indexPath];
}
[tableView reloadData];
}
Try this:
Declare in your .m file:
#interface MyViewController () {
NSIndexPath *__selectedPath;
}
In tableView:cellForRowAtIndexPath: check if given indexPath is the same as stored in ivar:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//configure cell
if ([__selectedPath isEqual:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
In tableView:didSelectRowAtIndexPath store pointer to selected NSIndexPath or nil if cell has been deselect
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
__selectedPath = indexPath;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
__selectedPath = nil;
}
}
I wrote it without checking in Xcode, so there could be some typos, but I show main idea.
In my opinion you shouldn't call [self checkMark]; in your tableView:cellForRowAtIndexPath: method.
Moreover if you want to have only one selected cell at a time, you should't create NSMutableArray to store NSIndexPath. It seems yours cellSelected stores 2 NSIndexPaths at a time, that why you have this strange behaviour.

iOS - UITableViewCell doesn't reload until I select another cell

I have a problem reloading selected cells.
Trying to follow a tutorial but now stuck with a strange problem.
I have made a list where selecting an item is suppose to show/remove a checkmark.
However, the cell is not updated until I select another cell in the list.
Any ideas?
I have attached the relevant sourcecode below.
Thanks, K
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
if(toDoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
toDoItem.completed = !toDoItem.completed;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
You've accidentally implemented didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath.
Your problem is tha tha you didn't use the didSelectRowAtIndexPath but the didDeselectRowAtIndexPath so right now every time you deselect your cell you updateyour cell :)

Resources