如何使用Xamarin.Forms在iOS中创建带圆角的进度条

时间:2018-02-05 05:36:30

标签: c# ios xamarin xamarin.forms xamarin.ios

我使用此SO Question的输入来使用AndroidDrawable平台创建带圆角的自定义进度条。 但是我无法为iOS创建相同的输出。

以下是Android的外观。 Android Sample

如何在iOS中创建相同的效果?

1 个答案:

答案 0 :(得分:5)

有很多方法可以做到这一点,我更喜欢使用CALayer UIView并添加CAShapeLayer来绘制“进度条”。

UIView ProgressBar示例:

enter image description here

public class ProgressView : UIView
{
    CAShapeLayer progressLayer;
    UILabel label;

    public ProgressView() { Setup(); }
    public ProgressView(Foundation.NSCoder coder) : base(coder) { Setup(); }
    public ProgressView(Foundation.NSObjectFlag t) : base(t) { Setup(); }
    public ProgressView(IntPtr handle) : base(handle) { }
    public ProgressView(CGRect frame) : base(frame) { Setup(); }

    void Setup()
    {
        BackgroundColor = UIColor.Clear;

        Layer.CornerRadius = 25;
        Layer.BorderWidth = 10;
        Layer.BorderColor = UIColor.Blue.CGColor;
        Layer.BackgroundColor = UIColor.Cyan.CGColor;

        progressLayer = new CAShapeLayer()
        {
            FillColor = UIColor.Red.CGColor,
            Frame = Bounds
        };
        Layer.AddSublayer(progressLayer);

        label = new UILabel(Bounds)
        {
            TextAlignment = UITextAlignment.Center,
            TextColor = UIColor.White,
            BackgroundColor = UIColor.Clear,
            Font = UIFont.FromName("ChalkboardSE-Bold", 20)
        };
        InsertSubview(label, 100);
    }

    double complete;
    public double Complete
    {
        get { return complete; }
        set { complete = value; label.Text = $"{value * 100} %"; SetNeedsDisplay(); }
    }

    public override void Draw(CGRect rect)
    {
        base.Draw(rect);
        var progressWidth = (rect.Width - (Layer.BorderWidth * 2)) * complete;
        var progressRect = new CGRect(rect.X + Layer.BorderWidth, rect.Y + Layer.BorderWidth, progressWidth, (rect.Height - Layer.BorderWidth * 2));
        progressLayer.Path = UIBezierPath.FromRoundedRect(progressRect, 25).CGPath;
    }
}

用法示例:

var progressView = new ProgressView(new CGRect(50, 50, 300, 50));
Add(progressView);
DispatchQueue.MainQueue.DispatchAsync(async () =>
{
    while (progressView.Complete <= 1)
    {
        InvokeOnMainThread(() => progressView.Complete += 0.05);
        await Task.Delay(1000);
    }
});