绘制方法覆盖后,UIProgressView不再更新

时间:2017-04-20 19:53:02

标签: xamarin xamarin.ios

我正在制作一个自定义UIProgressView,最终会有引号,所以我自然会覆盖Draw方法。但是,我注意到在覆盖设置到位后,即使调用SetProgress方法,用于递增和递减进度条的Draw方法也不再更新。

自定义类:

public class ModifiedProgressBar : UIProgressView
{
    public ModifiedProgressBar(IntPtr handle) : base(handle)
    {
    }

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

被叫:

private void UpdateDisplay(float step)
{
    this.modifiedProgressBar.SetProgress(step);
}
然后通过递增/递减按钮调用

UpdateDisplay。此代码与UIProgressView类以及未ModifiedProgressBar覆盖的Draw类完美匹配。 Progress属性也会使用新的设置值进行更新,视图不会更新。我试过调用SetNeedsDisplay,但没有强制视图更新。这里有什么发生的事情,有没有办法让这个正确绘制?提前谢谢!

2 个答案:

答案 0 :(得分:1)

您实际上需要提供绘图例程,而不是调用基础,当然也会根据Progress属性更改绘图。

像黄色矩形一样简单:

enter image description here

public override void Draw(CGRect rect)
{
    var color = UIColor.FromRGBA(1.0f, 1.0f, 0.0f, 1.000f);
    var rectanglePath = UIBezierPath.FromRect(new CGRect(rect.X, rect.Y, rect.Width * Progress, rect.Height));
    color.SetFill();
    rectanglePath.Fill();
}

或者是尖尖的东西:

enter image description here

public override void Draw(CGRect frame)
{
    var context = UIGraphics.GetCurrentContext();
    var color2 = UIColor.FromRGBA(0.199f, 0.018f, 0.018f, 1.000f);
    var shadow = new NSShadow();
    shadow.ShadowColor = UIColor.Black;
    shadow.ShadowOffset = new CGSize(3.1f, 3.1f);
    shadow.ShadowBlurRadius = 5.0f;
    UIBezierPath bezierPath = new UIBezierPath();
    bezierPath.MoveTo(new CGPoint(frame.GetMinX() + 0.00935f * frame.Width * Progress, frame.GetMinY() + 0.01351f * frame.Height));
    bezierPath.AddLineTo(new CGPoint(frame.GetMinX() + 0.99537f * frame.Width * Progress, frame.GetMinY() + 0.50000f * frame.Height));
    bezierPath.AddLineTo(new CGPoint(frame.GetMinX() + 0.99537f * frame.Width * Progress, frame.GetMinY() + 0.50000f * frame.Height));
    bezierPath.AddLineTo(new CGPoint(frame.GetMinX() + 0.00935f * frame.Width * Progress, frame.GetMinY() + 0.98570f * frame.Height));
    bezierPath.AddLineTo(new CGPoint(frame.GetMinX() + 0.00935f * frame.Width * Progress, frame.GetMinY() + 0.01351f * frame.Height));
    bezierPath.ClosePath();
    bezierPath.LineCapStyle = CGLineCap.Square;
    bezierPath.LineJoinStyle = CGLineJoin.Bevel;
    context.SaveState();
    context.SetShadow(shadow.ShadowOffset, shadow.ShadowBlurRadius, shadow.ShadowColor.CGColor);
    UIColor.Red.SetFill();
    bezierPath.Fill();
    context.RestoreState();
    color2.SetStroke();
    bezierPath.LineWidth = 1.0f;
    bezierPath.Stroke();
}

答案 1 :(得分:0)

UIProgressView使用一系列UIImageView个对象并拉伸其边界矩形以使进度增长。 UIImageView没有回复drawRect:rect

  

不要将图像视图用于自定义绘图。 UIImageView类不使用drawRect:方法绘制其内容。仅使用图像视图来显示图像。 https://apple.co/2HIGtOx

UIProgessView的常规用途是为语义层创建NSProgress对象(比如prog),为视图层提供基于UIProgressView的对象(通过设置observeProgress(https://apple.co/2vORFoh

来说明progView NSProgress个对象

简而言之:

progView.observedProgress = prog;

然后在语义层:

prog.completedUnitCount += 1;

跟踪您在语义操作中的进度,并同时神奇地更新视图的progView(即#34;观察")。这是我想将UIProgressView用作基类的最大原因。

上周,我在WWDC 2018的UI实验室与Apple工程师讨论了这个确切的话题。他们的反馈是:

  1. UIProgressView不是设计为子类,因此是 不支持(它们可能会破坏您的代码),只是
  2. 创建一个UIView并将您的进度指示器绘制到该
  3. 使用键值观察将接口代码与语义代码隔离开来。
  4. 我在GitHub(在Swift中)检查了几个例子:

    circular progress