0

我有一个无限旋转 UIImageView 形式的自定义活动指示器。这个惊人的活动指示器被放置在一个表格单元格中。

动画是这样实现的:

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat: M_PI * 2.0];
animation.duration = 1.0f;
animation.repeatCount = INFINITY;

[self.layer addAnimation:animation forKey:@"SpinAnimation"];



起初,它工作得很好......但是当单元格被滚动出表格的边界时,动画停止了,我不知道如何重置它....../:

请帮助...
提前非常感谢... :)

4

2 回答 2

2

原因是当prepareForReuse 工作您的应用程序进入后台模式时,rotation.z 键的动画变为 nil 。

考虑手动绘制活动指示器或尝试类似 https://github.com/airbnb/lottie-ios

活动指示器下方的方法可以在滚动/单元格/背景模式下正常滚动

我尝试了 rotation.z 和一些基于 CAReplicationLayer 的变通方法——在滚动/单元格/背景模式下都失败了

进度层外观

private func drawLoaderCircle() {

    let path = UIBezierPath(arcCenter: loaderViewCenter, radius: loaderCircleRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath

    setupGrapes(endAngle: 310, path: path)
}

private func setupGrapes(endAngle: CGFloat, path: CGPath) {

    let step: CGFloat = 2
    var grapeAnimationDelay: CFTimeInterval = 0

    for i in stride(from: 0, to: endAngle, by: step) {

        let radians = i * .pi / 180

        let x = loaderViewCenter.x + loaderCircleRadius * cos(radians)
        let y = loaderViewCenter.y + loaderCircleRadius * sin(radians)

        let grapeLayer = CAShapeLayer()
        grapeLayer.frame = CGRect(x: 0, y: 0, width: circleWidth + 0.2, height: circleWidth + 0.2)
        grapeLayer.position = CGPoint(x: x, y: y)
        grapeLayer.cornerRadius = grapeLayer.frame.width / 2
        grapeLayer.backgroundColor = loaderColor.cgColor

        grapeAnimationDelay += Double(rotateDuration * Double(step) / 360)
        let rotateGrapeAnimation = CAKeyframeAnimation(keyPath: "position")
        rotateGrapeAnimation.path = path
        rotateGrapeAnimation.beginTime = grapeAnimationDelay
        rotateGrapeAnimation.calculationMode = .linear
        rotateGrapeAnimation.repeatCount = .infinity
        rotateGrapeAnimation.isRemovedOnCompletion = false
        rotateGrapeAnimation.duration = rotateDuration

        grapeLayer.add(rotateGrapeAnimation, forKey: nil)

        progressLayer.addSublayer(grapeLayer)
    }

}
于 2019-01-20T02:29:32.353 回答
1

重复使用相应的单元格时,似乎删除了此动画。至少,animationDidStop当我从cellForItemAtIndexPath.

我能想到的最简单的解决方法:

您的表视图数据源:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if(cell && [cell conformsToProtocol:@protocol(CustomCellProtocol)])
    {
        [(id<CustomCellProtocol>)cell beforeDisplayed];
    }

    return cell;
}

你的手机:

static NSString* const kSpinAnimationKey = @"SpinAnimation";

@interface CustomCell () <CustomCellProtocol>
@end

@implementation CustomCell

-(void)startSpinAnimation
{
    CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    animation.fromValue = [NSNumber numberWithFloat:0.0f];
    animation.toValue = [NSNumber numberWithFloat: M_PI * 2.0];
    animation.duration = 1.0f;
    animation.repeatCount = INFINITY;

    [self.layer addAnimation:animation forKey:kSpinAnimationKey];
}

-(void)beforeDisplayed
{
    UIView* animatedView = self.contentView;
    if(![animatedView.layer animationForKey:kSpinAnimationKey])
    {
        [self startSpinAnimation];
    }
}
于 2014-04-29T19:11:23.307 回答