I have a custom uitableviewcell called customContactsTableViewCell. I am trying to use this code to update the uitableviewCell content
let cell1 = self.contactsTableView.dequeueReusableCell(withIdentifier: "contacts", for: IndexPath.init(row: index, section: 0)) as! customContactsTableViewCell
cell1.cellView.image = statusFinal.1
self.contactsTableView.reloadData()
But nothing happens. no errors and the cellview is not updated
Try:
let cell1 = tableView.cellForRow(at: IndexPath(row: index, section: 0)) as! customContactsTableViewCell
cell1.cellView.image = statusFinal.1
If you are created your tableview through Storyboard just go to your tableview and set cell custom class to customContactsTableViewCell And you'r cell identifier should be contacts if everything is already setup like this, then just check your these lines.
cell1.cellView.image = statusFinal.1
self.contactsTableView.reloadData()
After reloadData it redraw tableview again and setup data in it through this tableview Delegate function.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/// your code
}
It will again update your data with old data, Just save this data statusFinal.1 in your data model and then whenever you require reload, it will get update through updated data. Hope so you got the point, if need more info let me know.
Related
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.
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.)
I want to have ActivityIndicatorView inside each UITableViewCell and start animation after tap (to show that action is in progress). But I cannot start the animation effect.
I added ActivityIndicatorView to my cell prototype and connected it via #IBOutlet. This is my code to start animation after user selects table row:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedAction = actions[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as! ActionTableViewCell
cell.activityInProgressIndicator.startAnimating()
}
I also tried adding new instance of ActivityIndicatorView as cell.accessoryView. Without any effect.
I also tried to update the cell either via tableView.reloadData() (which I would like to avoid) and tableView.beginUpdates() and tableView.endUpdates()
Ideally this spinning indicator should be hidden but setting .isHidden = false in didSelectRowAt also does not work.
Just replace
let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell",
for: indexPath) as! ActionTableViewCell with below line
let cell = tableView.cellForRow(at: indexPath) as! ActionTableViewCell.
Hope it will work!!
The problem is that you're creating new instance of ActionTableViewCell when you use tableView.dequeueReusableCell inside didSelectRowAt, which is wrong.
You need to use something like this:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ActionTableViewCell else { return }
cell.activityInProgressIndicator.startAnimating()
}
This will fix your issue.
I Have a UITableView which is controlled by NSFetchedResultsController. I want to add single cell to the first row and make this cell static. In other words, there will be a button which will open another View Controller.
Until now, I was ok with fetched results controller and table. Now I'm a bit confused. How should I do this?
Instead using a header might be ok too, but I don't want this header to be on top all the time. I want this cell to be just like WhatsApp iOS "Create new group" cell on chats panel.
Thank you!
var dataArray = ["A","B","C"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArray.count+1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "CreateNewGroupCell") as! CreateNewGroupCell
return cell
}
else
{
// Get the data from Array
let data = self.dataArray[indexPath.row-1]
// Logic to show other cells
let cell = tableView.dequeueReusableCell(withIdentifier: "OtherCell") as! OtherCell
return cell
// ....
}
}
You will need to create tableview with number of rows fetched from NSFetchedResultsController +1. Also in cellForRowIndex method you will need to add a check like indexPath.row == 0 and in there you will make the changes.
Also you will have to add action for that button within that section. You can also set different custom tableview for first row.
It can be similar to following:
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row==0){
let cell = tableView.dequeueReusableCell(withIdentifier: "CellWithButton", for: indexPath) as! CellWithButton
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "OtherCells", for: indexPath) as! OtherCells
//here add data for cells from your array
}
return cell
}
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 !