You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift:如何设置CAShapeLayer的进度值并实现每秒进度+1的效果

这个需求完全可以实现,基于你已有的CAShapeLayer圆形进度条实现,仅需少量调整即可达到每秒跳跃固定数值的效果。

实现逻辑

你要的无平滑过渡的跳跃进度效果,核心是禁用CAShapeLayer修改strokeEnd属性时的默认隐式动画,再配合定时器每秒更新一次进度值即可。

具体实现步骤
  • 第一步:定义所需属性,包含当前进度值、已创建的CAShapeLayer实例、定时器实例
  • 第二步:创建每秒触发的定时器,每次触发时将进度值+1
  • 第三步:更新进度时关闭隐式动画,直接给strokeEnd赋值,即可实现无过渡的跳跃效果
代码示例

Swift 版本

// 声明属性
private var currentProgress: Int = 0
private let progressLayer = CAShapeLayer()
private var progressTimer: Timer?

// 启动进度更新定时器
private func startProgressUpdate() {
    // 按需设置最大进度,这里以100为例
    let maxProgress: CGFloat = 100
    
    progressTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
        guard let self = self, self.currentProgress < Int(maxProgress) else {
            self?.progressTimer?.invalidate()
            self?.progressTimer = nil
            return
        }
        self.currentProgress += 1
        // 转换为CAShapeLayer可用的0~1区间值
        let strokeEnd = CGFloat(self.currentProgress) / maxProgress
        // 关闭隐式动画,实现跳跃效果
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        self.progressLayer.strokeEnd = strokeEnd
        CATransaction.commit()
    }
    // 加入common runloop模式,避免滑动ScrollView时定时器暂停
    RunLoop.current.add(progressTimer!, forMode: .common)
}

// 页面销毁时记得销毁定时器
deinit {
    progressTimer?.invalidate()
}

Objective-C 版本

// 声明属性
@property (nonatomic, assign) NSInteger currentProgress;
@property (nonatomic, strong) CAShapeLayer *progressLayer;
@property (nonatomic, strong) NSTimer *progressTimer;

// 启动进度更新
- (void)startProgressUpdate {
    CGFloat maxProgress = 100;
    self.currentProgress = 0;
    
    self.progressTimer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:true block:^(NSTimer * _Nonnull timer) {
        if (self.currentProgress >= maxProgress) {
            [self.progressTimer invalidate];
            self.progressTimer = nil;
            return;
        }
        self.currentProgress += 1;
        CGFloat strokeEnd = self.currentProgress / maxProgress;
        
        [CATransaction begin];
        [CATransaction setDisableActions:true];
        self.progressLayer.strokeEnd = strokeEnd;
        [CATransaction commit];
    }];
    [[NSRunLoop currentRunLoop] addTimer:self.progressTimer forMode:NSRunLoopCommonModes];
}

// 页面销毁时销毁定时器
- (void)dealloc {
    [self.progressTimer invalidate];
}
注意事项
  • 如果你需要自定义每次跳跃的数值,只需要修改currentProgress += 1中的增量即可
  • 最大进度可以根据业务需求自由调整,只需要保证strokeEnd的最终计算结果在0~1区间即可
  • 定时器必须在页面销毁时手动调用invalidate方法,否则会出现内存泄漏

内容的提问来源于stack exchange,提问作者user17243660

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 02:15:05