How to call didDeselectRowAt of tableView in a collectionView - uitableview

I have a collectionView and a tableView. When I toggle a cell on tableView, it adds/removes that cell to collectionView. And remove a cell from collectionView when I click on it. I want to call didDeselctRowAt of tableView when clicking on cells of collectionView.
tableView(tableView, didDeselectRowAt: indexPath) // in collectionView
The above method is working. However, When I click tableView' cell again this method calls again. Is there any property like
cell.isDidDeselect = true // cell of tableView
To prevent calling again it.

Moved solution from question to answer:
Update and Answer
I found answer:
use
tableView.deselectRow(at: indexPath, animated: true)
tableView.delegate?.tableView!(tableView, didDeselectRowAt: indexPath)
instead of
tableView(tableView, didDeselectRowAt: indexPath)

Related

Get Info from CollectionView Cell Within TableView

I have a collectionView within a tableview and I am trying to access the collection view's indexPath in order to get its contents upon selecting it.
Here is my code:
TableView
//This grabs the indexPath of the collectionView Selected with its contents
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedDeal = dealArray[indexPath.row]
}
ViewController
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let cell = tableView.dequeueReusableCell(withIdentifier: "SpecialPicTableViewCell", for: indexPath) as! SpecialPicTableViewCell
//Defines the selected
let deal = cell.selectedDeal
//Grabs selected information here
dealSelected = deal.title ?? ""
//Then segues
performSegue(withIdentifier: "goToDeal", sender: nil)
tableView.deselectRow(at: indexPath, animated: true)
}
However, the selection does not register with the TableView. Nothing happens as a result.
The only information in the collection view is information you put there. You shouldn't need to get any information out of the collection view cell because you already have it.
The code you posted dequeues (possibly creates) a cell, cleans it up and gets it ready for use (possibly reuse.) That cell that you essentially created will know nothing about the data that is in the cell that was selected.
What you should be doing instead, is referring to the array where you store the deals to display and figuring out what deal is at the selected index path.

UITableView cells in random order after using scrollToRow

So after I add this code below the comment:
DispatchQueue.main.async {
self.tableView.reloadData()
// HERE
let indexPath = IndexPath(row: self.messages.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
My cells mess up (generated randomly) when scrolling. Before adding this code they behave as expected.
I think it has to do with the fact that cells are reused, and I don't know how to fix this.
Any explanations as to why?
cellForRowAt method for more detail:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.cellIdentifier, for: indexPath) as! MessageCell
cell.messageText.text = messages[indexPath.row].body
if Auth.auth().currentUser?.email == messages[indexPath.row].sender{
cell.isIncoming = false
} else {
cell.isIncoming = true
}
return cell
}
Cells are recycled. In your table view's data source, you need to dequeue a cell and fully configure it with data from your model.
If you allow your user to interact with your table view, you need to save those changes into your model so that if the cell scrolls off-screen, you recreate it correctly when it scrolls back on-screen.
You haven't provided enough information about how you set up your cells for us to provide more help than that.
If you want more specific help, edit your question to show your data source methods (in particular your tableView(_:cellForRowAt:) method.)

how to reload a collectionview that is inside a tableviewcell

I have a collectionView inside a tableViewCell
for example:
credit: How to use StoryBoard quick build a collectionView inside UITableViewCell
I would like to reload the collectionView when I update information.
I have put a print in the collectionView's cellForItemAtIndexPath to test if it is being called but it isn't. How can I get the collectionView to reload?
I found out how! In my tableViewCell class I just need to link the collectionView as an outlet so in my tableViewCell's cellForRowAtIndexPath I just needed to call cell.collectionView.reloadData()
Simplest Way
for cell in tableView.visibleCells {
(cell as? YourTableViewCell)?.collectionView.reloadData()
}
Or
If you need to reload Specific UICollectionView
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? YourTableViewCell {
cell.collectionView.reloadData()
}
1st on tableview cell create this function:
func collectionReloadData(){
DispatchQueue.main.async(execute: {
self.collectionView.reloadData()
})
}
then call it from
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { ...
cell.collectionReloadData()
create tags for collection view with indexPath.row of UITableView and create an instance of the UICollectionView using the tag and reload !

Swift: return to tableview after selecting a search result

I have successfully implemented a search function. I want to be able to search my list, select an item on the list, then return to the main tableview while the item remains selected. How do I do this?
This is the tableview without any selections or character typed into the searchbar. Items do not have a detail view. Items do have more information that can be retrieved, e.g. url. This data must be retrieved later when a user presses the "mail" button top left.
This is the list with search results. The grey highlight of the cell indicates that the cell is selected. How do I now return to the main tableview, whilst keeping the selection? I only see the cancel-button top right, the cross-button in the searchbar top middle, and the "search" button on the lower right part of the keyboard. None bring you back to the main tableview whilst storing the selection.
Based on the suggested answers, I was able to store the row's index path, using the function below:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let rowToSelect = indexPath
println(rowToSelect)
selectedCellTitle = selectedCell?.textLabel?.text ?? ""
println("The stored cell is called \(selectedCellTitle)")
}
However, I haven't succeeded in reselecting the row in the main tableview. My code is below. It looks like the constant "rowToSelect" is not carried over to another function (see the one before last line of code). How do I fix this?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
if tableView == self.searchDisplayController!.searchResultsTableView {
cell.textLabel?.text = filteredPublications[indexPath.row].valueForKey("fullTitle") as? String
cell.detailTextLabel?.text = filteredPublications[indexPath.row].valueForKey("journal") as? String
} else {
cell.textLabel?.text = publications[indexPath.row].valueForKey("fullTitle") as? String
cell.detailTextLabel?.text = publications[indexPath.row].valueForKey("journal") as? String
self.tableView.selectRowAtIndexPath(rowToSelect, animated: true, scrollPosition: .Top)
}
return cell
}
The UITableView Delegate has a function tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath. This function get’s called when a row is selected.
If you listen for this function and save the selected indexPath, you can use selectRowAtIndexPath to (re)select it in your main view.
Implement this function to listen for any selections made in your tableView
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//get back to your filled UITableView
//Save "indexPath" to a variable
}
When you get back to the view controller where you have your UITableView
self.tlbView.selectRowAtIndexPath(“above declared variable”, animated: true, scrollPosition: .Top)
If you're able to hold the index of the Cell in your tableViewController, you could use self.tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: .Top) as soon as you come back to your tableView. This will keep the cell grey like in your picture even if you scroll the table.

Hide label when UITableView Cell is tapped

I have a label within my cells that I would like to show/hide when tapped. I know that I have to get the index path of the cell that was tapped from within didSelectRowAtIndexPath. But I am unsure of how I then show/hide the label in that particular cell.
Am I able to show/hide it from within didSelectRowAtIndexPath, or is there a way to deal with it in cellForRowAtIndexPath and then update it?
I did some research into this but I really couldn't find a whole lot.
Here is all I have so far:
var selectedRowIndex: NSIndexPath = NSIndexPath(forRow: -1, inSection: 0)
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRowIndex = indexPath
}
Here is how you get to the cell from the index path:
let cell = tableView.cellForRowAtIndexPath(indexPath) as MyCustomCell
cell.myTextLabel.hidden = true
Also, depending on your needs, you might want to deselect the cell as well.
tableView.deselectRowAtIndexPath(indexPath)

Resources