Knowing when a UITableView is done loading its cells - ios

The purpose of this question is not to know when a UITableView is done loading its data (which has been answered in this post) but to know when a UITableView has done drawing all its cells.
Using the visibleCells property inside the
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
method doesn't work because when the tableview is loaded for the first time, no cells are visible yet.
The idea is to animate the cell appearance when the tableview is refreshed.
This seems like a complex task to perform but I'm surprised Apple didn't provide any delegate method to use when a tableview is done loading.

Better try this method, pass NSArray of indexPaths that you want to reload with given set of animation
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Hope it works

I don't believe there is a method that indicates when a table has loaded it's cells. However, you can achieve your goal of animating in the table cell whenever it is drawn.
Logic:
UITableView displays UITableViewCells as needed.
Each UITableViewCell is a subclass of UIView.
UIView has drawRect, which is called every time the view is drawn.
So, put your animation in UITableViewCell's drawRect method & it'll animated whenever it's drawn.
Implementation:
Create a subclass of UITableViewCell,
Apply this subclass to your table cells,
Add the drawRect method, and
Implement your animation in the drawRect method.
I have done this in one of my projects and it worked great. It draws the animation when the table is loaded or scrolled and when the display is rotated. With this approach you don't need to know when the table is done loading – each cell is simply animated whenever it is drawn.
One final note – if you put another view controller on top of your table view and then dismiss it, you may need to reload the table and set each UITableViewCell to setNeedsDisplay. This will force drawRect to be called again for each UITableViewCell.

Related

How to resume the CAAnimation group after cell reuse?

I wrote some CAAnimation code in Cell. It's working proper at the first show of cell. but after the cell reuse. The animations is stop. Almost all the way on internet. It remove the animation and add again. But I hope I can get the animation and resume again. Anyone know how to that? Thanks for your help.
I also find apple give a way to stop and resume the CAAnimation. But It's seem don't work in my project only use the resume code.
Here is the line. QA1673
I use CAAnimationDelegate to watch the animation status. When the cell scrolled out of bounds, They call the - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag to tell the animation is stop. so apple stop it not by accident.
That's the all info I got.
As you have discovered, the cell's awakeFromNib is only called once for a cell, even though it potentially will be reused many times. I would suggest to put your code as follows:
In UITableViewCell or sub-class
- (void)awakeFromNib
Called once for the lifetime of the cell.
Place initialization code that is independent of the cell's content.
- (void)prepareForReuse
Called when the cell is about to be re-cycled.
Place cleanup code that must be called before reusing the cell here. Usually you do not need to use this, but can put the code in cellForRowAtIndexPath instead. See below.
In class implementing UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Called for every cell the table view wants to display.
Place initialization code that is dependent of the cell's content here. I suggest you put your animation code here.

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.

make uipickerview appear between cells when touched cell

I like to implement UI like this screen.
as you see, when I touch a specific cell, pickerview appears at the bottom of that cell.
and it sits between two cell. and pickerview doesn't seem to be a subview of cell.
How do I implement this? I don't know where to start...
You can insert a new cell which contains a UIPickerView when user tap on a cell by using this method -
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Also for this you need to handle your data structure carefully by which you are populating your UITableView.
You can checkout this repo, it might help you -
https://github.com/saadnib/InsertPickerInTableView

iOS callback when uitableviewcell gets destroyed

As a user scrolls up and down in an uitableview cells get destroyed and created.
Is there a way to detect when a cell is going to be or has been destroyed?
Assuming that by "getting destroyed" you actually are referring to a cell getting reused, simply implement prepareForReuse within your UITableViewCell derived class.
prepareForReuse
Prepares a reusable cell for reuse by the table view's delegate.
- (void)prepareForReuse
Discussion
If a UITableViewCell object is reusable—that is, it has a reuse
identifier—this method is invoked just before the object is returned
from the UITableView method dequeueReusableCellWithIdentifier:. For
performance reasons, you should only reset attributes of the cell that
are not related to content, for example, alpha, editing, and selection
state. The table view's delegate in tableView:cellForRowAtIndexPath:
should always reset all content when reusing a cell. If the cell
object does not have an associated reuse identifier, this method is
not called. If you override this method, you must be sure to invoke
the superclass implementation.
Availability
Available in iOS 2.0 and later.
See Also
– initWithFrame:reuseIdentifier:
#property reuseIdentifier
Declared In
UITableViewCell.h
Without going into the implications of suitability or performance, another option might be to periodically check what cells remain visible, using the visibleCells method of the UITableView class:
- (NSArray *)visibleCells
As per the documentation:
Returns an array containing UITableViewCell objects, each representing a visible cell in the receiving table view.
You can subclass UITableViewCell and override it's dealloc method.
Any good reason to do it assuming you are reusing the cells to save the resources ?
What you're attempting to intercept is part of the internal implementation of UITableView and how it manages its cells. While there are ways in which you can attempt to intercept such behavior, I would suggest that you avoid using them, as there is no guarantee that future implementations of UITableView will maintain this behavior.
It would be better in cases such as this to consider a different approach: be it design and implement your own table class, or change your code logic.
As stated above, cells aren't destroyed when the leave the screen. However there are some things you can do, to track related actions, depending on what you are trying to do.
First there is a delegate message:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
This is called before a cell enters the screen. Another possibility is the already stated prepareForReuse method of a cell.
Another approach would be: Try and override willMoveToSuperview: or any other of the related methods. I am not sure if this is fired after the cell becomes invisible, but it might work.
Best regards,
Michael

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