This question already has answers here:
UITableView Multiple Selection
(11 answers)
Closed 6 years ago.
I know this question has been asked before, but there is a confusion among those. As i need multiple checkmark on cell and on clicking again on that cell checkmark should be set to none for that selected cell. i have tried this but all cell get selected doesnot none when again clicking on selected cell. i have tried this.
- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
myTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myTableViewCell" forIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
and in didSelectRowAtIndexPath
- (void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath )indexPath
{
myTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myTableViewCell" forIndexPath:indexPath];
if ( cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
and in didDeselectRowAtIndexPath
-(void)tableView:(UITableView )tableView didDeselectRowAtIndexPath:(NSIndexPath )indexPath
{
myTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myTableViewCell" forIndexPath:indexPath];
if ( cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Please help.
You just need to maintain the state of cell whether is it selected or not.
Try this in your cellForRowAtIndexPath.
if ([tableView.indexPathsForSelectedRows containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
Related
In single screen I have added UITableview and UICollectionview. I have added default delegate and datasource methods for both TableView and Collection View. but UITableView only little slow to load data. That data I have added statically that too load very slowly. Same code working fast in iPhone but iPad I am facing this slowness issues. Anyone know about this please help me do this.
I have found solution for that, Actually in my tableviewcellforrowatindexpath function i made some changes .
My current code following as,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
static NSString *cellId = #"SimpleTableId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell1 == nil) {
cell1 = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell2 == nil) {
cell2 = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
if(values == 1)
{
return cell;
}
else if(values == 2)
{
return cell1;
}
else
{
return cell;
}
}
I have changed like below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
static NSString *cellId = #"SimpleTableId";
if(values == 1)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
return cell;
}
else if(values == 2)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
return cell;
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
return cell;
}
}
Now my slowness issues solved as much expected.
This question already has answers here:
Select multiple rows in UITableview [duplicate]
(5 answers)
Closed 6 years ago.
I have list of states in UITableView.Now i want to select multiple row of UITableView and wanna get this selected row values in one array.how can i get this?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSMutableArray *arrData =[statearray objectAtIndex:indexPath.row];
NSLog(#"arrdata>>%#",statearray);
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [statearray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
You can call tableview.indexPathForSelectedRows. This will output an array with the indexpaths for all selected rows in your tableview!
This is how your code would look like in swift 3:
var values : [String] = []
let selected_indexPaths = tableView.indexPathsForSelectedRows
for indexPath in selected_indexPaths! {
let cell = tableView.cellForRow(at: indexPath)
values.append((cell?.textLabel?.text)!)
}
After running this code the values of all selected cells should be in the values array.
you can keep track of selected cells with below way
var selectedCells: [UITableViewCell] = []
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedCells.append(tableView.cellForRow(at: indexPath)!)
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let deselectedRow = tableView.cellForRow(at: indexPath)
if(selectedCells.contains(deselectedRow!)){
let indx = selectedCells.index(of: deselectedRow!)
selectedCells.remove(at: indx!)
}
}
Idea is to maintain array of selected cells when cell selection happens and remove cell once deselection is done
Best way is to get selected indexpaths using method
tableView.indexPathsForSelectedRows
you can get the data out in an array
var oldArray: [NSIndexPath] = [NSIndexPath.init(row: 0, section: 0), NSIndexPath.init(row: 1, section: 0), NSIndexPath.init(row: 2, section: 0), NSIndexPath.init(row: 3, section: 0)]
var newArray: [Int] = oldArray.flatMap { ($0.row) }
Like if we have array in form of oldArray, We can get only rows using flatMap.
There is default method of tableview,
self.tableView.indexPathsForSelectedRows
Which gives you an array of selected indexpaths. But you need to also set property of tableview
self.tableView.allowsMultipleSelection = true
If want back selcted rows to track,
NSArray *selectedRowsArray = [yourTableViewName indexPathsForSelectedRows];
Answer updated
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//the below code will allow multiple selection
if ([yourMutableArray containsObject:indexPath])
{
[yourMutableArray removeObject:indexPath];
}
else
{
[yourMutableArray addObject:indexPath];
}
[yourTableView reloadData];
}
-(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];
}
if ([yourMutableArray containsObject:indexPath])
{
//Do here what you wants
if (contentArray.count > 0) {
NSDictionary *dictObje = [contentArray objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#",[dictObje objectForKey:#"name"]];
}
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
//Do here what you wants
if (contentArray.count > 0) {
NSDictionary *dictObje = [contentArray objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#",[dictObje objectForKey:#"name"]];
}
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
When i select index 0 or 1 or any else that same time it also selected index according to above index
i need solution
there are many rows and when i select cell 1 same time another cell selected automatically..
#property (nonatomic, retain) NSIndexPath * checkedIndexPath;
in ViewDidLoad
self.checkedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];//Default 1st row will be checkMarked
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSimpleCell];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kSimpleCell]autorelease];
}
if (self.checkedIndexPath== indexPath)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *currentcell = [tableView cellForRowAtIndexPath:self.checkedIndexPath];
currentcell.accessoryType = UITableViewCellAccessoryNone;
self.checkedIndexPath = indexPath;
UITableViewCell *currentcell = [tableView cellForRowAtIndexPath:self.checkedIndexPath];
currentcell.accessoryType = UITableViewCellAccessoryCheckmark;
}
I want to apply checkmark as accessory type to a selected item in a uitable view. but the checkmark appears for all reused cells. How can we avoid this problem?
code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ([[[data objectAtIndex:indexPath.row] ringtone_id] isEqualToString:selId] ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
// Configure the cell...
cell.textLabel.text = [[[data objectAtIndex:indexPath.row] ringtone_name] stringByDeletingPathExtension];
return cell;
}
Try this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Configure the cell...
if ([[[data objectAtIndex:indexPath.row] ringtone_id] isEqualToString:selId] ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [[[data objectAtIndex:indexPath.row] ringtone_name] stringByDeletingPathExtension];
return cell; }
Hope this will help you.
you have to add the else case to unmark the cells that you don't want to be marked, like this:
if ([[[data objectAtIndex:indexPath.row] ringtone_id] isEqualToString:selId] ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
Try it this way:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Configure the cell...
if ([[[data objectAtIndex:indexPath.row] ringtone_id] isEqualToString:selId] ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [[[data objectAtIndex:indexPath.row] ringtone_name] stringByDeletingPathExtension];
return cell;
}
I want to make a table that user can select and deselect with a check mark:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
...;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
...;
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
...;
}
I was trying to remove the check mark when clicking on the check-marked cell again, but it takes 2 clicks to do that instead of one.
If I set selection style to default, when I click on a selected row, it removes the blue highlight; clicking again, it removes the check mark.
I also tried some conditional statements in didSelectRowAtIndexPath, but they only respond to second click as well.
What causes the problem and how do I fix it?
You can try this one:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger index = [[tableView indexPathsForVisibleRows] indexOfObject:indexPath];
if (index != NSNotFound) {
UITableViewCell *cell = [[tableView visibleCells] objectAtIndex:index];
if ([cell accessoryType] == UITableViewCellAccessoryNone) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
}
This should toggle the cell's checkmark on every touch.
If you additionally want only one cell to appear selected at a time, also add the following:
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger index = [[tableView indexPathsForVisibleRows] indexOfObject:indexPath];
if (index != NSNotFound) {
UITableViewCell *cell = [[tableView visibleCells] objectAtIndex:index];
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
If you don't want the blue hilight background, simply set the cell's selection style to UITableViewCellSelectionStyleNone once you create the cell.
Based on Starter's link to Apple docs (my code in Swift 3):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let cell = tableView.cellForRow(at: selectedIndexPath) {
cell.accessoryType = .none
}
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
selectedIndexPath = indexPath
}
The main point is to keep track of currently selected cell and change cell.accessoryType accordingly. Also don't forget to properly set cell.accessoryType in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) based on selectedIndexPath.
Check this Apple official doc
best solution ever
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (index != NSNotFound) {
UITableViewCell *cell = [[tableView visibleCells] objectAtIndex:index];
if (cell.accessoryType == UITableViewCellAccessoryNone)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
[self.tableName reloadData];
}
}
This helps in toggling the checkmarks (remove the check mark when clicking on the check-marked cell again)
You can use this:
You can use this:
if tableView.cellForRow(at: indexPath)?.accessoryType == .checkmark { tableView.cellForRow(at: indexPath)?.accessoryType = .none } else { tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } tableView.deselectRow(at: indexPath, animated: true)