I am trying to call (cellForRowAt indexPath: IndexPath)
method manually from a button how can i accomplish that for the record i already have tried reload data method on the UITableView.
It did not work.
self.myTableView.reloadData()
Why i need to do that is because i am trying to implement a solution from stackoverflow the solution looks like this:
func configureVisibleCells(for tableView: UITableView?, animated: Bool) {
self.tableView(tableView, configureRowsAtIndexPaths: tableView?.indexPathsForVisibleRows, animated: animated)
}
func tableView(_ tableView: UITableView?, configureRowsAtIndexPaths indexPaths: [Any]?, animated: Bool) {
for indexPath in indexPaths as? [IndexPath] ?? [] {
let cell: UITableViewCell? = tableView?.cellForRow(at: indexPath)
if cell != nil {
self.tableView(tableView, configureCell: cell, forRowAt: indexPath, animated: animated)
}
}
}
func tableView(_ tableView: UITableView?, configureCell cell: UITableViewCell?, forRowAt indexPath: IndexPath?, animated: Bool) {
// Cell configuration
}
"Configure the Cell in the
tableView(_ tableView: UITableView?, configureCell cell: UITableViewCell?, forRowAt indexPath: IndexPath?, animated: Bool) method and call this method in your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell .
and when you need to reload visible cells call the method
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell"
Now i need to call it as the guy who posted the solution said so.
Do not call cellForRowAtIndexPath manually. That is to be called only by the system otherwise it will result in undefined behaviour. Instead what you can do is call a function that will in turn will call cellForRowAtIndexPath internally. This is because before calling cellForRowAtIndexPath, system needs to call other methods to be able to layout the cell properly.
For example: number of rows, sections, height, etc.
You can use reloadRows(at:with:) function of UITableView to reload the rows of visible cells.
Have a look at this: documentation.
Related
I have a tableview implemented. The list shows fine, but I want to detect when the row selection has been changed. I am trying to do a certain action when the row selection is changed, for example, print("row selection has changed ")
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "exploreCell", for: indexPath)
cell.textLabel?.text = tableArray[indexPath.row]
return cell
}
I hope the question is clear.
You can observer selection state from this 2 delegate methods. So when you select any cell it will call didSelectRowAt delegate method and if you tap on selected cell again it will call didDeselectRowAt
Make sure to set tableView selection property to multiple selection incase if you want user to select multiple cell
tableView.allowsMultipleSelection = true
Swift Delegate methods.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Your code here
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
//Your code here
}
I have a UITableView nested inside another UITableView.
In the nested tableView, when the user taps on a cell, the cell does highlight, but the delegate method didSelectRowAt indexPath: is not being called.
Other delegate methods are being called, for example methods like willDisplay cell: forRowAt indexPath: or scrollViewDidScroll(_:). So this tells me that the delegates etc. are connected correctly.
In another part of the same application I am using the same kind of structure, UITableView inside another UITableView and there it works fine.
I compared the two extensively, so far I haven't found the difference, and no clue why one should work and the other not!
Please see the implementation of the nested UITableViewCell.
It would be nice if the console would log the line "touch detected".
It does log the lines "scrolling" and "will display cell".
import UIKit
class TestTableViewCell: UITableViewCell {
}
extension TestTableViewCell: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableView.dequeueReusableCell(withIdentifier: "FileCell")!
}
}
extension TestTableViewCell: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("touch detected")
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print("will display cell")
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrolling")
}
}
Solution was very simple at last.
I had a UITapGestureRecognizer setup for the outer UITableView.
I had this there to dismiss the keyboard on tap.
After removing the UITapGestureRecognizer it started working fine.
I completely overlooked this, but it's solved now!
I'm making a custom action which perform an animation of a GitHub repo.
Here is my code of VC which has the TableView:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
var done1=UITableViewRowAction(style: .normal, title: "done", handler: UITableViewRowAction!, indexPath: indexPath){
CustomCell.makeanimate(CustomCell)
}
return(done1)
}
and here is the code of CustomClass :
func makeanimate() {
self.checkTest.setOn(true, animated: true)
}
I want to call makeanimate when I tap done1, but I get an error saying use of instance member 'makeanimate' on type 'customCell'
I believe makeanimate is an instance method, but you are calling it as if it was a class method in your code. You need to get a cell instance and then call makeanimate via that cell.
I want to add animation when UITableView load cells (From top to Bottom) But getting no idea about this, please someone help me.
Below added a simple table view delegate methode with an array(arrHeader).
Thanks in advance
let arrHeader = ["City1", "City2", "City3"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrHeader.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")
cell?.textLabel?.text = arrSubHeader[indexPath.row]
return cell!
}
Put your animation code in this UItableView delegate method:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//TODO: animation code
}
this delegate method is called every time a new or old cell is going to be displayed on the iPhone/iPad screen.
So if you try something in this block with the cells it will reflect on them.
optional func tableView(_ tableView: UITableView,
didEndDisplaying cell: UITableViewCell,
forRowAt indexPath: IndexPath) { }
this method gets called after a cell is being displayed.
Here is the github link for the Example:
Visit: https://github.com/subhajitregor/TableCellCardDropAnimationExample
I'm implementing a UITableViewController in my app and I want to add a possibility of sliding/swiping a cell on my tableview, exactly like in this answer: Swipe-able Table View Cell in iOS 9 but with a difference that it works only for one specific cell, not all of them. So far I have:
class MyTableViewController: UITableViewController {
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: (UITableView!), commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: (NSIndexPath!)) {
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
var deleteAction = UITableViewRowAction(style: .Default, title: "Hello There!") {action in
print("some action!!")
}
return [deleteAction]
}
}
and it adds the swiping for all cells and I want to add it only to the 3rd one on my list (cells are not generated dynamically). Is there a way of doing that?
You can check the indexPath of the cell which is given as parameter and return the appropriate response based on that. Furthermore, you could also check the type of your cell using func cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell? if you have different cells or so.
Index path is a class. You can get the index of the current row from the indexPath using indexPath.row.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
if ((indexPath.row % 3) == 0) {
return true
} else {
return false
}
}