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]; }
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:
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.
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.
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.
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:
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
:
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With