Hide the circle on UITableView with multiple selection - objective-c

I have a UITableView that hast multiple selection enabled.
Some of my cells are not to be selected. For those I implement:
in the tableView:cellForRowAtIndexPath:
I set cell.selectionStyle = UITableViewCellSelectionStyleNone;
and in tableView:didSelectRowAtIndexPath:
I call [self.tableView deselectRowAtIndexPath:indexPath animated:NO];.
This works fine. My only caveat is that the little circle left of the cell still appears. It does not get checked when a user taps the cell, but I would like for it not to be shown, when a cell is "unselectable".
How can I hide those circles for certain cells?
Thanks

You have to implement the tableView:canEditRowAtIndexPath: method in your table view datasource. It will let you prevent the cells you want to be editable and thus the circles not to be shown.
Beware that setting cell.selectionStyle = UITableViewCellSelectionStyleNone; does NOT prevent the cell to be selected. It just removes any visual clue on a selected cell.

Try this...
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if([[tableView indexPathsForSelectedRows] containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

Subclassing UITableViewCell and adding following method works for me:
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(false, animated: true);
}

Related

pop up a view when i clicked button on table view cell

I have a button on table view cell if I click the button a pop up view will be appeared and the remaining cells will be animated to downwards like animation.and the cell having sub views it will open like a plist in ios if i click the sub view cell it will open the next level sub cells. The tableview must be like below images
Cells and sub-cells must be like this. Can any one assist me?
I have done this before. Just use the following code. Create a custom cell class having the cell and followed view in the cell view but show only what is to be shown by using heightforrowatindexpath method uitableview class. Here is the code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (checkHeight == indexPath.row)
return 185;
else
return 80;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
FAQCell *cell = (FAQCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"FAQCell" owner:self options:nil];
cell = myCell;
myCell = nil;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell.quesText setFont:[UIFont fontWithName:#"CaviarDreams" size:16]];
[cell.ansText setFont:[UIFont fontWithName:#"CaviarDreams" size:16]];
// check for the row for which the background color has to be changed
if (checkHeight == indexPath.row)
[cell.bgView setBackgroundColor:[UIColor colorWithRed:0.3333 green:0.7373 blue:0.4588 alpha:1.0]];
else
[cell.bgView setBackgroundColor:[UIColor colorWithRed:0.9176 green:0.3765 blue:0.2980 alpha:1.0]];
return cell;
}
#pragma mark -
#pragma mark Tableview Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
checkHeight = indexPath.row;
// reload the data of the table
[tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, tableView.numberOfSections)] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Let me know if you face any issue.
Check out this custom view -
Custom Tree View
Expandable Table View

Why won't UITableViewCellAccessoryCheckMark Go Away?

Okay so I am slowly figuring this out. Just one more issue I am having. I am using a string and saying that if the string is equal to the cell text to put a checkmark on it when it loads the tableView.
Here is my code for that:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if ([cell.textLabel.text isEqualToString:transferData]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
I am then telling it to remove that checkmark and add the checkmarks accordingly when being selected:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
cell.accessoryType = UITableViewCellAccessoryNone;
UITableViewCell *cellCheck = [tableView
cellForRowAtIndexPath:indexPath];
cellCheck.accessoryType = UITableViewCellAccessoryCheckmark;
transferData = cellCheck.textLabel.text;
NSLog(#"%#", transferData);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:indexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
Everything works fine, except when it first loads. For some reason when I select on another cell, the checkmark that is originally loaded with the tableView won't go away. Why is this?
You are making a common mistake.
When selecting the cell, you are setting the state of the check mark directly. What you should be doing is setting the state of the checkmark in the data source and let the table cell configure itself from the data source.
Edited example for an exclusive checked table view
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *changedIndexPaths = nil;
NSIndexPath *currentCheckedIndexPath = [self indexPathOfCurrentCheckedObject];
if (currentCheckedIndexPath && ![currentCheckedIndexPath isEqual:indexPath]) {
// There is currently a checked index path - unselect the data source and
// add it to the changed index array.
[[self.tableData objectAtIndex:currentCheckedIndexPath.row] setChecked:NO];
changedIndexPaths = #[indexPath, currentCheckedIndexPath];
} else{
changedIndexPaths = #[indexPath];
}
[[self.tableData objectAtIndex:indexPath.row] setChecked:YES];
[self.tableView reloadRowsAtIndexPaths:changedIndexPaths withRowAnimation:UITableViewRowAnimationNone];
}
I have a new sample app you can download to see the whole project:
You need:
if (self.selectedPath && [indexPath isEqual:self.selectedPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
Cells get reused. If you conditionally set any cell attribute, you must always have the 'else' part to reset the attribute.
Edit: With the above change in your cellForRowAtIndexPath: method, do the following in your didSelectRowAtIndexPath: method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *oldSelection = self.selectedPath;
if (self.selectedPath) {
UITableViewCell* uncheckCell = [tableView cellForRowAtIndexPath:self.selectedPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
self.selectedPath = nil;
}
if (oldSelection == nil || ![indexPath isEqual:oldSelection]) {
UITableViewCell* checkCell = [tableView cellForRowAtIndexPath:indexPath];
checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
self.selectedPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath];
}
And get rid of the didDeselectRowAtIndexPath: method.
And of course you need the selectedPath property of type NSIndexPath *.
This code lets you pick 0 or 1 row.

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;
}

Why are checkmarks not being displayed when UITableView.allowsMultipleSelection is enabled?

I have a UITableView in an iOS5.1 app where I set
self.tableView.allowsMultipleSelection=YES;
The Apple documentation states "When the value of this property is YES, a check mark is placed next to each row that is tapped. Tapping the row again removes the check mark.".
I am able to select multiple rows as the background is set to Blue. However, no checkmarks are displayed. Does the checkmark need to be set as shown below in didSelectRowAtIndexPath because I am using custom UITableViewCells?
cell.accessoryType = UITableViewCellAccessoryCheckmark;
I do the checkmarks manually in my uitableviewcell subclasses. You are going to have to do the UITableViewCellAccessoryCheckmark manually in didSelectRowAtIndexPath and keep a track of which one is selected. I would recommend something like so:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableview cellAtIndex:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryCheckmark)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
}
note: I did not test this, but should give you the basic idea. Let me know if you have any questions. Did you try using a default uitableviewcell and see if it did the checkmark? I would not think a subclass would have a problem, as long as you are not modifying in the subclass.
Another option is to use tableView:didDeselectRowAtIndexPath: in addition to tableView:didSelectRowAtIndexPath:
- (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;
}

Cell accessorytype doesn't reload on [tableview reloadData]

I'm very new to iPhone programming, so my problem might be caused by total lack of knowledge of very basic principles.
I'm developing an iPhone app that has two Views. The first view has two buttons, when one of the buttons is pressed, a modalview popsup with a tableview. This table view is populated differently depending of what button is pressed. If button button1 is pressed the tableview is populated with the button1Data. The user can select cells, and if this is done the cells accessorytype is set to UITableViewCellAccessoryCheckmark. I then save the name of the checked cells into tableViewListChecked, so it can later be decided what cell are supposed to be checked as the data changes.
The problem is as following: after the modalview is dismissed, and I select button2 the cells that was selected in button1Data is still selected in button2Data. It is clear to me that the function [theTableView reloadData] is working since the data does change, however the accesorytupes is still the same until i scroll the cells off the screens.
P.S. If I do in fact scroll cells of the screen there accessorytype is set correctly.
- (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] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [tableViewList objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (![tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableViewListChecked addObject:[NSString stringWithString:cell.textLabel.text]];
}
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryNone;
[tableViewListChecked removeObject:[NSString stringWithString:cell.textLabel.text]];
}
}
Thanks for you help!
If the cell is not nil (if it has been dequeued from the table view) then you don't actually, as it is, change the accessory type. Drop the else, ie change
else if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
to
if ([tableViewListChecked containsObject:[NSString stringWithString:cell.textLabel.text]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
It sounds like you are reusing the same instance of the UITableView each time you present the modal view, in which case, what is happening to the tableViewListChecked array? You are swapping out data in the tableViewList; but are you employing some strategy to persist the list of checked items between taps on button1 and button2?
If the guys here didn't helped you, you can just set:
cell.accessoryType = UITableViewCellAccessoryNone every time the user clicks on button2