UIActivityIndi​​catorView在UITableViewCell中停止动画

Rak*_*esh 25 iphone uiactivityindicatorview ios

我有一个表视图,在该表视图中,我有一个UIActivityIndi​​cator,每个单元格中都有一个按钮.现在单击该按钮我想启动ActivityIndi​​cator动画,它的开始.但问题是当我滚动表格视图时它会停止动画.这是我的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;
}
Run Code Online (Sandbox Code Playgroud)

和我的按钮的选择器方法是

-(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];
}
Run Code Online (Sandbox Code Playgroud)

use*_*609 71

我想我可以了解旋转器何时以及如何停止在细胞中旋转.我已经UIActivityIndicatorView使用我自己的类重载了startAnimatingstopAnimating函数,并在其中添加了断点.我做了一个简单的单元格,上面只有一个微调器.我在IB中将微调器的Animating属性设置为true: 在此输入图像描述

现在发生了什么.前两个屏幕截图有一个堆栈跟踪,指示两个操作(停止动画并启动它们)在同一个私有函数中一个接一个地发生_didMoveFromWindow:toWindow: 在此输入图像描述 在此输入图像描述

在我看来,这是在细胞创建流程中发生的,所以首先它没有动画初始化,然后IB设置启动并启动动画.现在这里是有趣的部分,当微调器停止动画时: 在此输入图像描述

因此,当细胞从屏幕上移除时,旋转器似乎一直在旋转,并且当细胞准备prepareForReuse通过私有函数再次显示在屏幕上时停止旋转(_removeAllAnimations这似乎是递归地迭代所有子视图).问题在于,出于某种原因,UIKit的私有函数永远不会重新启用动画,startAnimating永远不会被调用.实际上,IMO禁用动画是真正的问题.

我提出的解决方案,它并不完美,但它显然是Apple对我们的期望,是将UITableViewCell子类化为包含微调器的单元并在prepareForReuse中重新启用它们:

class SpinnerCell: UITableViewCell {
    @IBOutlet weak var spinner: UIActivityIndicatorView?

    override func prepareForReuse() {
        super.prepareForReuse()
        if let spinner = self.spinner {
            spinner.startAnimating()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在Obj-C:

@interface SpinnerCell

@property (weak) IBOutlet UIActivityIndicatorView *spinner;

@end

@implementation SpinnerCell

- (void)prepareForReuse {
    [super prepareForReuse];
    [self.spinner startAnimating];
}

@end
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.值得一个最好的答案旗帜. (3认同)
  • OFM是这种情况的完美前缀 (2认同)