In UITableView, what's the delegate for "visibleCells"? - ios

When cells come in and out of device's screen, I want my viewController to know exactly what came and what went out. Is there a way to do this?

There isn't a delegate method just for "visible cells". There isn't anything called when a cell leaves the screen. There really isn't anything when a cell becomes visible.
There is the cellForRowAtIndexPath data source method. This is called when a cell is needed.
There is the willDisplayRowAtIndexPath delegate method. This is called when a cell will be displayed.
There is the didEndDisplayingCell delegate method. This is called when a cell is removed from the table view.
There is the indexPathsForVisibleRows method on UITableView. This lets you know what rows are currently in view.
There is the prepareForReuse method on UITableViewCell. This lets a cell reset itself to be reused for another row.
Better describe what you are trying to accomplish in order to get a more specific answer.

Related

cellForRowAtIndexPath is being called for non visible cells also

tableview data source method cellForRowAtIndexPath is being called for the non visible rows also which is creating a problem in pagination in tableview. Did anyone face this issue?
The system calls this method to prepare cells ahead of time, so scrolling is smoother and more responsive. If you want to fetch more data as the user scrolls down/up you should rather implement UITableViewDelegate method tableView(_:willDisplay:forRowAt:) - this method is called just before the cell is displayed to the user.

Should I set the cell on cellForItemAtIndexPath or willDisplayCell?

this page that talks about tricks to smooth table view scrolling, says the table view cells should be drawn not on tableView:cellForRowAtIndexPath: but rather on tableView:willDisplayCell:forRowAtIndexPath:.
I have tried that approach on and I see no difference on my initial tests. Is there any truth about that?
should I really use tableView:willDisplayCell:forRowAtIndexPath: to create the cell, set thumbnails, texts, etc. instead of tableView:cellForRowAtIndexPath:?
Yes its true that both perform the same function but use cellForRowAtIndexPath for tableview where datasource has to be implemented as cellForRowAtIndexPath works fast and you must return reused cell identifiers quickly. This is a method of datasource of tableview
tableView:willDisplayCell:forRowAtIndexPath is a method of delegate & not datasource. This method is called exactly before loading cells in UITableView bounds.

What is wrong if cellForItemAtIndexPath: is called in didSelectItemAtIndexPath:

I called cellForItemAtIndexPath: in the didSelectItemAtIndexPath: method. The result was that didSelectItemAtIndexPath: was only called one time per cell. So I can tap the first time on a cell, then I can tap on another cell, but if I tap on the first cell again the didSelectItemAtIndexPath is not called anymore (but all other "new" cells).
Now I'm not calling cellForItemAtIndexPath: anymore and now didSelectItemAtIndexPath: works as expected. But why I'm not allowed to do this? Any reasons for this?
The collection view is caching instances of cells for you and you dequeue them when you create the cell at an index path. The collection view is making some assumptions about what's going on when you do this, so if you start making multiple requests for cells at the same index path strange things start to happen. Sometimes this results in visual issues, sometimes interaction issues.
If you want to get the cell at a specified index path you should ask the collection view directly instead of using your own delegate method, this will give you the existing cell on screen rather than a new cell.

Check if a UITableViewCell is selected, and the cell went off screen

I have a custom UITableViewCell that dequeueReusableCells. I have an int called selectedRow which gets the selected rows number in the method of didSelectRowAtIndexPath. I then pass selectedRow to an int called rowNumber which is in the class of my customCell.
In customCell.m, I have the method prepareForReuse. In that I made an NSLog of rowNumber.
What I want to do is: if a row is selected and that row went off screen, then perform some code. I would probably have to use prepareForReuse, but I don't know what to do in it.
I know it's a bit complicated, but if you have any questions, then I'd be happy to answer
Actually, you don't need to call prepareForReuse directly as it would be called automatically:
this method is invoked just before the object is returned from the
UITableView method dequeueReusableCellWithIdentifier:.
and as you don't know what to do in it, note:
For performance reasons, you should only reset attributes of the cell
that are not related to content, for example, alpha, editing, and
selection state
UITableViewCell Class Reference
You can use - (void)tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath; in UITableViewDelegate to know which cell is scrolled off screen.
However, this method is iOS6+ only.
You're over complicating things. You don't have to do prepareForReuse the in the custom cell.
Take a look at this.
http://www.icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/
Its pretty similar for storyboards.

How to notice if a UITableViewCell has left the visible area?

I'm stuck with the problem that I want to know in my UITableView if a specific UITableViewCell, let's say the first, is still visible or already off the visible area.
I would also be ok to know if the cell of interest is now beeing reused at an other indexPath of the table.
One of my - later and frustrated approaches - was to have a thread that knows the first cell object and frequently pings it to check if a value I did set in the cell changed. Obviously a not so good solution.
Andy ideas how to do this right?
Remember that UITableView is UIScrollView subclass and its delegate also confirms to UIScrollViewDelegate protocol as well.
So in your table delegate you can implement scrollViewDidScroll: method and check contentOffset - if it's more then first cell height then first cell is not visible. You can also get the array off all currently visible cells using -visibleCells method, but I think knowing contentOffset should be enough.

Resources