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

如何在Xamarin.iOS中实现圆形脉冲动画?附代码实现

在Xamarin.iOS中实现圆形脉冲动画

我帮你整理并优化了Xamarin.iOS下的圆形脉冲动画实现代码,基于你参考的思路调整了C#端的适配细节,下面是完整的可运行实现:

// 声明全局数组存储脉冲图层
CAShapeLayer[] arrLayerShapes = new CAShapeLayer[2];

void CreatePulse() 
{
    // 禁用动画视图的交互,避免干扰
    vwShowAnimation.UserInteractionEnabled = false;

    for (int i = 0; i < 2; i++) 
    {
        // 创建圆形路径,以视图中心为原点
        var centerPoint = new PointF(0, 0);
        var circularPath = UIBezierPath.FromArc(
            center: centerPoint,
            radius: UIScreen.MainScreen.Bounds.Size.Width / 2,
            startAngle: 0,
            endAngle: 2 * (float)Math.PI,
            clockwise: true
        );

        // 初始化脉冲图层
        var circularPulseLayer = new CAShapeLayer();
        circularPulseLayer.Path = circularPath.CGPath;
        circularPulseLayer.LineWidth = 2.5f;
        circularPulseLayer.FillColor = UIColor.Clear.CGColor;
        circularPulseLayer.StrokeColor = UIColor.FromRGB(36, 229, 186).CGColor;
        circularPulseLayer.Opacity = 0;
        circularPulseLayer.LineCap = CAShapeLayer.CapRound;
        // 将图层定位到承载视图的中心
        circularPulseLayer.Position = new CGPoint(
            vwAnimateLayer.Frame.Size.Width / 2, 
            vwAnimateLayer.Frame.Size.Height / 2
        );

        vwAnimateLayer.Layer.AddSublayer(circularPulseLayer);
        arrLayerShapes[i] = circularPulseLayer;
    }

    // 设置定时器,循环触发脉冲动画
    NSTimer.CreateScheduledTimer(2.3, true, (timer) => 
    {
        DispatchQueue.MainQueue.DispatchAfter(DispatchTime.Now, (long)(0.2 * NSEC_PER_SEC), () => 
        {
            AnimateCircularPulseAt(0);
            DispatchQueue.MainQueue.DispatchAfter(DispatchTime.Now, (long)(0.4 * NSEC_PER_SEC), () => 
            {
                AnimateCircularPulseAt(1);
            });
        });
    });
}

// 核心动画方法
void AnimateCircularPulseAt(int index) 
{
    var targetLayer = arrLayerShapes[index];
    targetLayer.StrokeColor = UIColor.FromRGB(36, 229, 186).CGColor;

    // 缩放动画:从0放大到0.9倍
    var scaleAnimation = CABasicAnimation.FromKeyPath("transform.scale.xy");
    scaleAnimation.From = NSNumber.FromFloat(0);
    scaleAnimation.To = NSNumber.FromFloat(0.9f);

    // 透明度动画:从0.9淡到0
    var opacityAnimation = CABasicAnimation.FromKeyPath("opacity");
    opacityAnimation.From = NSNumber.FromFloat(0.9f);
    opacityAnimation.To = NSNumber.FromFloat(0);

    // 组合动画
    var groupAnimation = new CAAnimationGroup();
    groupAnimation.Animations = new CAAnimation[] { scaleAnimation, opacityAnimation };
    groupAnimation.Duration = 2.3f;
    groupAnimation.RepeatCount = nint.MaxValue;
    groupAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);

    targetLayer.AddAnimation(groupAnimation, "groupanimation");
}

关键实现说明

  • 使用两层CAShapeLayer实现交错脉冲效果,让动画衔接更流畅,避免单一图层重复动画的断层感
  • 通过CAAnimationGroup将缩放和透明度动画绑定,同步实现脉冲的扩散和淡出效果
  • 用NSTimer配合DispatchQueue的延迟调度,控制两个脉冲层的启动时机差,营造连续的脉冲视觉
  • 选择EaseOut计时函数,让动画的收尾阶段更自然柔和

自定义调整建议

  • 修改StrokeColor可以更换脉冲的颜色,LineWidth调整线条粗细
  • 调整scaleAnimation.To的值可以改变脉冲的最大扩散范围
  • 修改groupAnimation.Duration和定时器间隔,能控制脉冲的频率和速度
  • 若需要停止动画,可调用arrLayerShapes[index].RemoveAnimation("groupanimation"),并调用timer.Invalidate()销毁定时器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:39:01