xamrin.ios рисует круговой индикатор выполнения от верхнего края вместо правого - PullRequest
0 голосов
/ 15 мая 2019

Я работаю над приложением xamarin.forms. для этого мне нужен круговой прогрессбар. Я почти заставил его работать в xamarin.ios, используя CustomRenderer, но на самом деле это не то, что я хотел.

Мой круговой индикатор выполнения в рендерере xamarin.ios работает, но начинается с правого края связующего прямоугольника. но я хочу, чтобы это началось с верхнего края по часовой стрелке.

Я пытался изменить начальный угол на -90 или 270, но все равно он начинается с правой стороны, а иногда и не работает. Я не уверен, в каком состоянии он не работает, но я думаю, что когда я использую Math.PI константу в коде, Draw никогда не вызывает. Я сослал эту ссылку.

class NativeProgressBarRenderer : ViewRenderer
    {
        private bool _sizeChanged = false;
        //private CG _paint;
        private CGRect _ringDrawArea;
        private nfloat _radius;
        const float FULL_CIRCLE = 2 * (float)Math.PI;
        // int _radius = 10;
        float _lineWidth = 10;
        nfloat _percentComplete = 0.0f;
        UIColor _backColor = UIColor.LightGray; //UIColor.FromRGB(46, 60, 76);
        UIColor _frontColor = UIColor.Green; //UIColor.FromRGB(234, 105, 92);

        protected override void OnElementPropertyChanged(object sender, 
        System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == ProgressBar.ProgressProperty.PropertyName ||
                e.PropertyName == PlayerProgressBar.RingThicknessProperty.PropertyName ||
                e.PropertyName == PlayerProgressBar.RingBaseColorProperty.PropertyName ||
                e.PropertyName == PlayerProgressBar.RingProgressColorProperty.PropertyName)
            {
                SetNeedsLayout();
                SetNeedsDisplay();
            }

            if (e.PropertyName == VisualElement.WidthProperty.PropertyName ||
                e.PropertyName == VisualElement.HeightProperty.PropertyName)
            {
                _sizeChanged = true;
                SetNeedsLayout();
                SetNeedsDisplay();
            }
        }

        public override void Draw(CoreGraphics.CGRect rect)
        {
            base.Draw(rect);

            using (CGContext g = UIGraphics.GetCurrentContext())
            {
                var progressRing = (PlayerProgressBar)Element;

                // Get Metrics
                var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;

                // Screen density
                var density = mainDisplayInfo.Density;

                _lineWidth = (float)Math.Ceiling(progressRing.RingThickness * density);

                var diameter = Math.Min(this.Bounds.Width, this.Bounds.Height);
                _radius = (int)(diameter / 2) - _lineWidth;

                _backColor = progressRing.RingBaseColor.ToUIColor();
                _frontColor = progressRing.RingProgressColor.ToUIColor();
                _percentComplete = (float)progressRing.Progress;

                var x = Bounds.GetMidX();
                var y = Bounds.GetMidY();

               //DrawGraph(g, Bounds.Left, Bounds.Top); // Tried to change x,y 
               DrawGraph(g, Bounds.GetMidX(), this.Bounds.GetMidY());
            };
        }

        public void DrawGraph(CGContext g, nfloat x, nfloat y)
        {
            //g.ScaleCTM(1, -1);
            //g.TranslateCTM(0, -Bounds.Height);
            //g.RotateCTM(270);

            g.SetLineWidth(_lineWidth);

            // Draw background circle
            CGPath path = new CGPath();
            _backColor.SetStroke();
            path.AddArc(x, y, _radius, 270, _percentComplete * FULL_CIRCLE, true);
            g.AddPath(path);
            g.DrawPath(CGPathDrawingMode.Stroke);

            // Draw overlay circle
            var pathStatus = new CGPath();
            _frontColor.SetStroke();

            //CGAffineTransform cGAffineTransform = new CGAffineTransform();
            //cGAffineTransform.Rotate(-90);    // This also doesn't work

            // Same Arc params except direction so colors don't overlap
            pathStatus.AddArc(x, y, _radius, 0, _percentComplete * FULL_CIRCLE, false);
            g.AddPath(pathStatus);
            g.DrawPath(CGPathDrawingMode.Stroke);

            //cGAffineTransform.Invert();
        }

Я ожидаю запустить его с вершины круга. Пожалуйста, помогите!

Спасибо

1 Ответ

1 голос
/ 16 мая 2019

Это потому, что начальный угол не начинается в 0 часов.Вот его система координат по умолчанию:

enter image description here

Таким образом, каждый угол должен быть минус 0,5π.Измените свой код как:

// Draw overlay circle
var pathStatus = new CGPath();
_frontColor.SetStroke();
pathStatus.AddArc(x, y, _radius, -0.25f * FULL_CIRCLE, (_percentComplete-0.25f) * FULL_CIRCLE, false);
g.AddPath(pathStatus);
g.DrawPath(CGPathDrawingMode.Stroke); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...