Selecting every row in TableView including off-screen rows
You don't.
You can't select all cells because they're being reused, which means only enough cells exist.
When the "Acknowledge" button is pressed, you can get the data from your datasource, the one you're consuming to create your UITableView
.
Note: If there is a state change when that button is pressed, you should iterate through your datasource and update your objects. And then you .reloadData()
.
Updates based on your question update, this is how you iterate through your datasource.
var dataClassArr = [DataClass]()
var result = [String]()
dataClassArr.append(DataClass(id: "1"))
dataClassArr.append(DataClass(id: "42")) // just for example, you should remove those.
for element in dataClassArr {
result.append(element.id)
}
print(result) // ["1", "42"] -> based on example values.
iOS having issues with UITableView programmatically selecting multiple cells and displaying a check
Override the setSelected
method in the custom tableview cell class,
and use tableview.selectRow(at:)
function to select cells.
Use tableView.indexPathsForSelectedRows
to get selected indexPaths in the table.
Here is a good implementation.
https://github.com/yonat/SelectionList
Reply To New Issue:
Please follow the steps.
viewDidLoad
orviewWillAppear
methodvar itemsToBeSelected: [String]?
var listItems: [String]?
....
override func viewDidLoad() {
super.viewDidLoad()
if let selected = self.itemsToBeSelected, let listItems = self.listItems {
selected.forEach { (item) in
if let index = listItems.index(of: item) {
let indexPath = IndexPath(item: index, section: 0)
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
}self.itemsToBeSelected
means they need to be selected by default in the list when the view controller appears. it's just an array ofString
in the above example.cellForRowAt
methodNo need to call
cell.isSelected = true/false
orcell.isHighlighted = true/false
if the cell is a custom cell, you can just apply the content to the cell only. and in the custom cell class, just override setSelected method.
class ExpansionBayCell {
....
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.checkBox.isChecked = self.isSelected
}
}when it's time to get all selected values and close the view controller
func btnDonePressed() {
guard let indexPaths = tableView.indexPathsForSelectedRows else {
btnBackPressed()
return
}
let items = indexPaths.map { self.listItems[$0.row] }
completion(items)
btnBackPressed()
}
How to Programmatically Pre-select Cells in a Multi-select UITableView in iOS
You should manage it entirely using your data model.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// Assumption: item is a class, so changes are reflected in array as expected
let item = items[indexPath.row]
item.isSelected.toggle()
cell!.accessoryType = item.isSelected ? .checkmark : .none
}
This way there's always one source of truth, your data model. Your tableView instance should not need to remember anything for you, it's driven by the data you provide.
If you go this way, you don't need to implement didDeselect
delegate method OR set allowsMultipleSelection
to true
.
-didSelectRowAtIndexPath: not being called
It sounds like perhaps the class is not the UITableViewDelegate
for that table view, though UITableViewController
is supposed to set that automatically.
Any chance you reset the delegate to some other class?
Manually call didSelectRowatIndexPath
You need to pass a valid argument, if you haven't declared indexPath
in the calling scope then you'll get that error. Try:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:ROW_YOU_WANT_TO_SELECT inSection:SECTION_YOU_WANT_TO_SELECT]
[self tableView:playListTbl didSelectRowAtIndexPath:indexPath];
Where ROW_YOU_WANT...
are to be replaced with the row and section you wish to select.
However, you really shouldn't ever call this directly. Extract the work being done inside tableView:didSelectRowAtIndexPath:
into separate methods and call those directly.
To address the updated question, you need to use the indexPathsForSelectedRows
method on UITableView
. Imagine you were populating the table cell text from an array of arrays of strings, something like this:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tv dequeue...];
NSArray *rowsForSection = self.sectionsArray[indexPath.section];
NSString *textForRow = rowsForSection[indexPath.row];
cell.textLabel.text = textForRow;
return cell;
}
Then, to get all the selected text, you'd want to do something like:
NSArray *selectedIndexPaths = [self.tableView indexPathsForSelectedRows];
NSMutableArray *selectedTexts = [NSMutableArray array];
for (NSIndexPath *indexPath in selectedIndexPaths) {
NSArray *section = self.sectionsArray[indexPath.section];
NSString *text = section[indexPath.row];
[selectedTexts addObject:text];
}
selectedTexts
would at that point contain all selected information. Hopefully that example makes sense.
How to select item in collectionview programmatically?
You can simply use this after [self.collectionView reloadData]
[self.collectionView
selectItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]
animated:YES
scrollPosition:UICollectionViewScrollPositionCenteredVertically];
where index
is the index number for the selected student.
Using a button to deselect cells in a collectionview
It is a bad idea to store selected index paths, as these are coupled to the collection view. If you store the selected items then you can always determine the appropriate index path, using the item's index in the array. You can also determine an item quickly from a given index path.
In the code below I have used the type Item
for your underlying item, but it could be String
or Int
or any object type. If you use your own class or struct, ensure you make it conform to Equatable
and Hashable
.
var allItems:[Item]
var selectedItems[Item]
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == allItemsCV {
let item = allItems[IndexPath.row]
if let itemIndex = selectedItems.index(of:item) {
selectedItems.remove(at:itemIndex)
selectedItemsCV.deleteItems(at: [IndexPath(item: itemIndex, section:0)])
} else {
selectedItems.insert(item, at: 0)
selectedItemsCV.insertItems(at: [IndexPath(item: 0, section:0)])
}
allItemsCV.deselectItem(at: indexPath, animated: true)
// cell for item at indexPath needs to render the selected/deselected
state correctly based on the item being in the selectedItems array
allItemsCV.reloadItems(at: [indexPath])
}
}
@IBAction func removeButtonPressed(_ sender: UIButton) {
//...
if let selectedItemPaths = selectedItemCV.indexPathsForSelectedItems {
var allItemIndexPaths = [IndexPath]()
var tempSelectedItems = Array(selectedItems) // Need to use a temporary copy otherwise the element indexes will change
for itemPath in selectedItemPaths {
let removeItem = selectedItems[itemPath.item]
if let removeIndex = tempSelectedItems.index(of: removeItem) {
tempSelectedItems.remove(at: removeItem)
}
if let allItemsIndex = allItems.index(of: removeItem) {
allItemIndexPaths.append(IndexPath(item: allItemsIndex, section: 0))
}
}
selectedItems = tempSelectedItems // Selected items array without the removed items
selectedItemsCV.deleteItems(at:selectedItemPaths)
allItemsCV.reloadItems(at: allItemIndexPaths) // Reload to update the selected status
}
}
Related Topics
Swift Running Code in Periodically Background
Place Multiple Scn Objects in Touchesbegan Method
Spritekit: Sprites Are Moving Through Each Other with a Physicsbody Already Set
Use Tableviewcontroller Inside Skscene
Connecting Avaudiosourcenode to Avaudiosinknode Does Not Work
Get Out of Navigation Controller and Go Back to Tab Bar View
Is It a Good Way to Access Instance Variable with Self? If I Use a Lot
Streaming .M3U8 Using Mpmovieplayercontroller Does Not Work
Swift Protocol That Is Using an Enum with Generic Associated Type
How to Use The Spritekit Method Body(At: Cgpoint)
Swiftui Navigationview Starting Inside Itself
Create Skspritenode with an Asset Programmatically
Protocol Extension Doesn't Work with Rct_Export_View_Property
Swift Dictionary Initialization of Custom Type Gives: '>' Is Not a Postfix Unary Operator Error
Change The 2Nd and 3Rd Pickerview Acording to What Row from The 1St Picker Is Selected