在 UIView::drawRect() 之外绘制 UIBezierPath?

Posted

技术标签:

【中文标题】在 UIView::drawRect() 之外绘制 UIBezierPath?【英文标题】:Draw UIBezierPath outside of UIView::drawRect()? 【发布时间】:2015-12-08 07:37:12 【问题描述】:

我正在尝试围绕视图边缘绘制一组小圆圈,以反映我在我的应用中控制的物理灯光(像素)。这些圆圈会经常改变颜色。所以我创建了一个 PixelSimulator 对象来将每个圆圈绘制到一个自定义 UIView 对象中。

这是相关代码

class PixelSimulator 
  let size: CGSize;
  let color: UIColor;
  let pixelPath: UIBezierPath;

  init (point: CGPoint, size: CGSize, pixel: Pixel) 
    self.point = point;
    self.size = size;
    self.pixel = pixel;

    pixelRect = CGRect(origin: point, size: size);
    pixelPath = UIBezierPath(ovalInRect: pixelRect);

    color = pixel.color;
  

  func render () 
    UIGraphicsBeginImageContext(size);

    color.setFill();
    pixelPath.fill();

    UIGraphicsEndImageContext();
  

我尝试过使用CGContextAddEllipseInRect(context, pixelRect) 的不同方法,但无济于事。我也尝试在render() 方法中声明pixelPath,也无济于事。

我需要更改什么才能让我的 bezierPath 随时绘制到屏幕上,在 drawRect() 内部还是外部?

【问题讨论】:

您对图像上下文的计划是什么?你什么时候调用渲染? 当相应的物理光的颜色发生变化时,我会打电话给render() 从哪里来?在绘制矩形?将视图设置为在更改时显示?我不会使用图像上下文,我会直接绘制到视图或图层。 物理灯的颜色在应用程序的其他地方发生了变化。实际上,当物理光的颜色发生变化时,对应的PixelSimulatorcolor 会更改为匹配并调用render()。这发生在drawRect() 之外。如果我每次颜色变化时都画一个图层,我最终会不会有很多图层?那会是个问题吗?如果没有,您能否发布一个解释如何的答案? 【参考方案1】:

我会删除图像上下文并直接绘制。我只会从 draw rect 内部调用 render

当颜色发生变化时,我会更新相应的模拟器并发布通知,让“系统”知道它发生了。在这种情况下,通知是合适的,因为您不想知道对更改事件感兴趣的内容,并且可能对系统中的多个内容感兴趣。

当您的视图控制器收到通知时,它只是在视图上调用setNeedsDisplay,这将导致模拟器在下一个绘制周期被渲染。

【讨论】:

这种方法很有效,而且可能比我想象的要高效得多。非常感谢。

以上是关于在 UIView::drawRect() 之外绘制 UIBezierPath?的主要内容,如果未能解决你的问题,请参考以下文章

UIView drawRect 安静崩溃

透明背景 UIView drawRect 圆圈

如何为手动“动画”重新排队对 UIView drawRect 的请求

iOS8 问题 - UIView drawRect 未被调用

让 UIView drawRect 发生在后台线程中

基准 UIView drawRect: 方法