Animate加载微调器弧Xamarin.iOS

时间:2017-11-01 14:45:23

标签: ios xamarin.ios

在我的Xamarin.iOS应用程序中,我正在尝试为加载微调器设置动画。我可以绘制圆和圆弧,但我不知道如何为它设置动画。这是我的加载微调器的类:

public class LoadingSpinnerView : UIView
{
    private CAShapeLayer _thinCirlce;
    private CAShapeLayer _arc;

    public LoadingSpinnerView()
    {
        _arc = new CAShapeLayer();
        _arc.LineWidth = 3;
        _arc.StrokeColor = UIColor.Blue.CGColor;
        _arc.FillColor = UIColor.Clear.CGColor;

        _thinCirlce = new CAShapeLayer();
        _thinCirlce.LineWidth = 1;
        _thinCirlce.StrokeColor = UIColor.Red.CGColor;
        _thinCirlce.FillColor = UIColor.Clear.CGColor;

        Layer.AddSublayer(_thinCirlce);
        Layer.AddSublayer(_arc);
    }

    private nfloat _angle;
    public nfloat Angle
    {
        get
        {
            return _angle;
        }

        set
        {
            _angle = value;
        }
    }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();

        _thinCirlce.Path = UIBezierPath.FromOval(new CoreGraphics.CGRect(0, 0, Frame.Width, Frame.Height)).CGPath;

        nfloat radius = Frame.Width / 2;
        _arc.Path = UIBezierPath.FromArc(new CoreGraphics.CGPoint(radius, radius), radius, 0, Angle, true).CGPath;
    }
}

我希望能够为它制作动画,如下所示:

UIView.Animate(5, () => { _loadingSpinnerView.Angle = 3.14f; }); // This doesn't actually work...

2 个答案:

答案 0 :(得分:1)

准备使用控件。只需在Storyboard中将控件设置为UIView。

[Register(nameof(CircleLoadingView))]
public class CircleLoadingView : UIView
{
    public CircleLoadingView(IntPtr handle) : base(handle)
    {
    }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();

        SetUpAnimation(this.Layer, new CGSize(Frame.Width, Frame.Height), UIColor.Red);
    }

    public void SetUpAnimation(CALayer layer, CGSize size, UIColor color)
    {
        var beginTime = 0.5;
        var strokeStartDuration = 1.2;
        var strokeEndDuration = 0.7;

        var strokeEndAnimation = CABasicAnimation.FromKeyPath("strokeEnd");
        strokeEndAnimation.Duration = strokeEndDuration;
        strokeEndAnimation.TimingFunction = CAMediaTimingFunction.FromControlPoints(0.4f, 0.0f, 0.2f, 1.0f);
        strokeEndAnimation.From = NSNumber.FromFloat(0);
        strokeEndAnimation.To = NSNumber.FromFloat(1);

        var strokeStartAnimation = CABasicAnimation.FromKeyPath("strokeStart");
        strokeStartAnimation.Duration = strokeStartDuration;
        strokeStartAnimation.TimingFunction = CAMediaTimingFunction.FromControlPoints(0.4f, 0.0f, 0.2f, 1.0f);
        strokeStartAnimation.From = NSNumber.FromFloat(0);
        strokeStartAnimation.To = NSNumber.FromFloat(1);
        strokeStartAnimation.BeginTime = beginTime;

        var groupAnimation = new CAAnimationGroup
        {
            Animations = new CAAnimation[] {/*rotationAnimation,*/ strokeEndAnimation, strokeStartAnimation },
            Duration = strokeStartDuration + beginTime,
            RepeatCount = float.PositiveInfinity,
            RemovedOnCompletion = false,
            FillMode = CAFillMode.Forwards
        };

        var circle = CreateCircle(size, color);
        var frame = CGRect.FromLTRB(
            (layer.Bounds.Width - size.Width) / 2,
            (layer.Bounds.Height - size.Height) / 2,
            size.Width,
            size.Height
        );

        circle.Frame = frame;
        circle.AddAnimation(groupAnimation, "animation");
        layer.AddSublayer(circle);
    }

    private CAShapeLayer CreateCircle(CGSize size, UIColor color)
    {
        var layer = new CAShapeLayer();
        var path = new UIBezierPath();
        path.AddArc(new CGPoint(size.Width / 2, size.Height / 2),
            size.Width / 2,
            -(float)(Math.PI / 2),
            (float)(Math.PI + Math.PI / 2),
            true);
        layer.FillColor = null;
        layer.StrokeColor = color.CGColor;
        layer.LineWidth = 2;

        layer.BackgroundColor = null;
        layer.Path = path.CGPath;
        layer.Frame = CGRect.FromLTRB(0, 0, size.Width, size.Height);

        return layer;
    }
}

答案 1 :(得分:0)

我明白了。这是我的其他Xamarin开发人员使用的加载微调器类。您可以根据自己的要求进行调整。

public class LoadingSpinnerView : UIView
{
    private CAShapeLayer _thinCirlce;
    private CAShapeLayer _arcLayer;

    public LoadingSpinnerView(nfloat radius)
    {
        UIColor.Red.SetColor();
        _thinCirlce = new CAShapeLayer();
        _thinCirlce.LineWidth = 1;
        _thinCirlce.Path = UIBezierPath.FromOval(new CoreGraphics.CGRect(0, 0, radius * 2, radius * 2)).CGPath;
        _thinCirlce.StrokeColor = UIColor.Red.CGColor;
        _thinCirlce.FillColor = UIColor.Clear.CGColor;
        Layer.AddSublayer(_thinCirlce);

        UIColor.Blue.SetColor();
        UIBezierPath arcPath = new UIBezierPath();
        arcPath.LineWidth = 4;
        arcPath.LineCapStyle = CGLineCap.Round;
        arcPath.LineJoinStyle = CGLineJoin.Round;
        arcPath.AddArc(new CoreGraphics.CGPoint(radius, radius), radius, 0, 2 * 3.14f, true);

        _arcLayer = new CAShapeLayer();
        _arcLayer.Path = arcPath.CGPath;
        _arcLayer.StrokeColor = UIColor.Blue.CGColor;
        _arcLayer.FillColor = UIColor.Clear.CGColor;
        _arcLayer.LineWidth = 4;
        _arcLayer.StrokeStart = 0;
        _arcLayer.StrokeEnd = 1;

        if (_arcLayer.SuperLayer != null)
        {
            _arcLayer.RemoveAllAnimations();
            _arcLayer.RemoveFromSuperLayer();
        }
    }

    public void StartAnimation()
    {
        Layer.AddSublayer(_arcLayer);

        CABasicAnimation animation = new CABasicAnimation();
        animation.KeyPath = "strokeEnd";
        animation.Duration = 3;
        animation.From = NSNumber.FromFloat(0);
        animation.To = NSNumber.FromFloat(1);
        _arcLayer.AddAnimation(animation, null);
    }

    public void StopAnimation()
    {
        _arcLayer.RemoveAllAnimations();
        _arcLayer.RemoveFromSuperLayer();
    }
}