Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIActivityIndicatorView stops animating in UITableViewCell

I have one table view and in that table view i have one UIActivityIndicator with one button in every cell . Now on click on that button i want to start ActivityIndicator animating, its starting. But the problem is when i scroll the table view it stops animating. Here is my code for cellForRowAtIndexPath

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"txDevicesListCellID"];     if (cell == nil) {         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"txDevicesListCellID"];     }     UIButton *buttonutton = (UIButton *)[cell viewWithTag:103];     UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *) [cell viewWithTag:104];     button.tag = indexPath.row;     return cell; } 

and selector method for my button is

-(IBAction)recevierButtonClick:(id)sender{     UIButton *button = (UIButton *)sender;     NSInteger index = button.tag;     NSIndexPath* indexpath = [NSIndexPath indexPathForRow:serialNumber inSection:0];     UITableViewCell* cell = [self.myTableView cellForRowAtIndexPath:indexpath];     activityIndicator = (UIActivityIndicatorView*)[cell viewWithTag:index];     [activityIndicator startAnimating]; } 
like image 801
Rakesh Avatar asked Feb 26 '15 08:02

Rakesh


People also ask

What is a uitableviewcell?

The visual representation of a single row in a table view. A UITableViewCell object is a specialized type of view that manages the content of a single table row. You use cells primarily to organize and present your app’s custom content, but UITableViewCell provides some specific customizations to support table-related behaviors, including:

How do I control when an activity indicator animates or stops?

You control when an activity indicator animates by calling the startAnimating () and stopAnimating () methods. To automatically hide the activity indicator when animation stops, set the hidesWhenStopped property to true. You can set the color of the activity indicator by using the color property.

How do I make an activity indicator view active?

While the data is being loaded, an application typically displays an activity indicator view to inform the user that something is happening. Often, this is done by dynamically adding an instance of UIActivityIndicatorView as a subview of either the current view or one of the view's ancestors and making the indicator active.

How do accessory views work in a custom cell?

Cells display accessory views on the trailing edge of their content area. When you put your table into edit mode, the cell adds a delete control to the leading edge of its content area, and optionally swaps out an accessory view for a reorder control.


1 Answers

I think I can shed some light into when and how the spinners stop spinning in cells. I've subclassed UIActivityIndicatorView with my own class overloading the startAnimating and stopAnimating functions and put breakpoints in them. I've made a simple cell with only a spinner on it of my class. I've set the spinner's Animating property to true in IB: enter image description here

Now here's what happens. First two screenshots have a stack trace that indicates the two actions (stopping animations and starting them) are happening one after the other, in the same private function _didMoveFromWindow:toWindow: enter image description here enter image description here

It seems to me this is happening in the cell creation flow, so first it's initialized with no animation and then the IB settings kick in and start the animation. Now here's the interesting part, when the spinner stops animating: enter image description here

So seems that the spinner keeps spinning when the cell is removed from the screen and is stopped when the cell is prepared to be shown on screen again (prepareForReuse) via the private function _removeAllAnimations, which seems to iterate recursively all child views. The problem is that for some reason the UIKit's private functions never re-enable the animations and the startAnimating never gets called. Actually IMO the disabling of animations is the real problem.

The solution that I propose, and it's not perfect but it's apparently what Apple expects of us, is subclassing the UITableViewCell for cells that contain spinners and re-enabling them in prepareForReuse:

class SpinnerCell: UITableViewCell {     @IBOutlet weak var spinner: UIActivityIndicatorView?      override func prepareForReuse() {         super.prepareForReuse()         if let spinner = self.spinner {             spinner.startAnimating()         }     } } 

Or in Obj-C:

@interface SpinnerCell  @property (weak) IBOutlet UIActivityIndicatorView *spinner;  @end  @implementation SpinnerCell  - (void)prepareForReuse {     [super prepareForReuse];     [self.spinner startAnimating]; }  @end 
like image 173
user3099609 Avatar answered Oct 02 '22 20:10

user3099609