user
user

Reputation: 39

UIActivityIndicator disappears

I have tableView with rows. If I click on row UIActivityIndicator start animating. But if I scroll tableView indicator disappears. How to fix it?

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(0, 0, 24, 24);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = spinner;
[spinner startAnimating];

Upvotes: 1

Views: 874

Answers (3)

Leon
Leon

Reputation: 3726

While the answers here are not exactly wrong, I think they don't cover the specific issue with a UIActivityIndicatorView inside a UITableViewCell.

I have encountered a similar issue with a custom cell which only contains a an activity indicator. If I set the indicator to start animating when the cell is initialised it loads correctly and the indicator is spinning. However, when the cell is dequeued the indicator is missing.

Following the instructions here I tried setting hidesWhenStopped to false and this time the indicator is visible when the cell is dequeued, but the animation has stopped. So the only thing I can deduce from this is when the cell is removed from the table the system automatically stops the indicator from animating.

The fix is the same as described in the other answers and when dequeueing the cell you need to call startAnimating() on the indicator.

Upvotes: 0

Duncan C
Duncan C

Reputation: 131418

This isn't a "what should I add to the code" question. This is a "I don't understand how table views work" question.

Telling you line-by-line what code to change won't help you. Instead, you need to study and understand the way table views work.

Table view cells get created, then reused over and over. When a cell scrolls off-screen, the system removes the cell from the screen and puts it in the "recycle bin". When a new row scrolls into view, the system tries to take a cell out of the recycle bin and use that to display the info for the newly exposed row rather than creating a new cell. It only creates a brand-new cell if there are no cells of the desired type in the recycle bin. Once you've created enough cells to fill the screen, when you scroll, the system probably won't need to create any new cells.

Back to your activity indicator on a cell.

You add an activity indicator to a cell and start it spinning. Then the user scrolls that cell off-screen. That cell will get reused to display a different row. Likely at some point you'll see a newly exposed cell with an activity indicator that you're not expecting.

If the user then scrolls back to the row that you added an activity indicator to before, it won't have a spinning activity indicator unless you set up the new cell for that row to have one, or the cell you get from the recycle bin happens to have a spinning activity indicator.

Any time you change the state of a cell, you need to save info about what you did to your data model ("the cell at row 6 is waiting on a download").

Then, in your cellForRowAtIndexPath method, you need to fully configure the cell. Create your cell prototypes so the cell always has an activity indicator, but it's hidden if not spinning. If a cell for a row needs an activity indicator to be spinning, set it to spinning. If it does NOT need a spinning activity indicator, set explicitly set the indicator to the NOT spinning state (because you may be dealing with a recycled cell that was dumped into the recycle bin with a spinning activity indicator). Also set all text fields/labels/text views to their default states. Assume that every single view on the cell that might have been changed from the default state WAS changed from the default state, and explicitly set it to the default state.

Upvotes: 1

Artem Novichkov
Artem Novichkov

Reputation: 2341

It happens because your cell reuse while scrolling. You need to save state for animating of UIActivityIndicator in your model and reload needed cell by index.

Upvotes: 2

Related Questions