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

Swift实现UIView连续批量波纹:间隔重复无限循环方案问询

iOS UIView 批次式波纹效果实现方案

要实现连续生成4-5个波纹→间隔一段时间→重复该过程的效果,核心是分两步控制动画时序:让同批次内的波纹按小延迟依次出现,再让整个波纹批次按固定间隔无限循环。以下是修改后的完整实现代码:

波纹效果扩展方法

import UIKit

extension UIView {
    // 批次式波纹效果:可自定义波纹数量、间隔等参数
    func addBatchRipple(rippleCount: Int = 4, 
                        rippleDelay: TimeInterval = 0.2, 
                        batchInterval: TimeInterval = 3, 
                        animationDuration: TimeInterval = 1) {
        let ripplePath = UIBezierPath(ovalIn: bounds)
        let shapePosition = CGPoint(x: bounds.midX, y: bounds.midY)
        
        // 生成单批次波纹的内部方法
        func generateRippleBatch() {
            for i in 0..<rippleCount {
                let rippleLayer = CAShapeLayer()
                rippleLayer.bounds = bounds
                rippleLayer.path = ripplePath.cgPath
                rippleLayer.fillColor = UIColor.clear.cgColor
                rippleLayer.strokeColor = UIColor.systemBlue.cgColor
                rippleLayer.lineWidth = 1
                rippleLayer.position = shapePosition
                rippleLayer.opacity = 0
                
                layer.addSublayer(rippleLayer)
                
                // 缩放动画
                let scaleAnim = CABasicAnimation(keyPath: "transform.scale")
                scaleAnim.fromValue = CATransform3DIdentity
                scaleAnim.toValue = CATransform3DMakeScale(2, 2, 1)
                
                // 透明度动画
                let opacityAnim = CABasicAnimation(keyPath: "opacity")
                opacityAnim.fromValue = 1
                opacityAnim.toValue = 0
                
                // 组合动画组
                let animationGroup = CAAnimationGroup()
                animationGroup.animations = [scaleAnim, opacityAnim]
                animationGroup.timingFunction = CAMediaTimingFunction(name: .easeOut)
                animationGroup.duration = animationDuration
                // 每个波纹延迟启动,实现连续弹出效果
                animationGroup.beginTime = CACurrentMediaTime() + Double(i) * rippleDelay
                animationGroup.isRemovedOnCompletion = false
                animationGroup.fillMode = .forwards
                
                rippleLayer.add(animationGroup, forKey: "ripple-\(i)")
                
                // 动画结束后自动移除图层,避免内存堆积
                DispatchQueue.main.asyncAfter(deadline: .now() + animationGroup.beginTime + animationDuration) {
                    rippleLayer.removeFromSuperlayer()
                }
            }
        }
        
        // 立即生成第一批次波纹
        generateRippleBatch()
        
        // 设置批次循环:每隔指定间隔生成一批波纹
        Timer.scheduledTimer(withTimeInterval: batchInterval, repeats: true) { _ in
            generateRippleBatch()
        }
    }
}

调用示例

@IBOutlet weak var sView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    sView.layer.cornerRadius = sView.bounds.width / 2
    sView.layer.borderWidth = 2
    sView.layer.borderColor = UIColor.systemBlue.cgColor
    
    // 调用波纹效果,可按需调整参数匹配目标样式
    sView.addBatchRipple(rippleCount: 4, rippleDelay: 0.2, batchInterval: 3, animationDuration: 1)
}

关键实现说明

  • 批次内波纹时序控制:通过animationGroup.beginTime给每个波纹设置递增的启动延迟,实现连续弹出的视觉效果。
  • 批次循环机制:使用Timer定时触发波纹批次生成,满足“间隔一段时间重复”的需求。
  • 内存优化:动画结束后自动移除波纹图层,避免图层长期堆积占用内存。
  • 参数可定制:方法支持调整波纹数量、单波纹间隔、批次间隔、动画时长,可快速匹配目标效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:53