在哪种情况下drawRect没有收到UIView的完整框架?

时间:2013-10-03 18:04:29

标签: ios cocoa-touch uiview

我正在编写一个补丁托架控件,我正在使用UIViews绘制补丁之间的链接。

这些链接是大型UIView的子视图,UIView本身是UIScrollView的子视图。

链接可能变得非常大,通常是屏幕大小的四倍。 当其中一个结束补丁移动时,需要重新绘制链接。

但是,有些情况下只有部分链接可见。

仪器表示大部分时间都花在我的QCLink drawRect方法上。

我已经检查过每次需要重新绘制此QCLink时,使用QCLink的完整边界调用drawRect方法。

这种情况我只需要重绘一部分UIView(drawRect :)中的rect参数吗?

以下是一些屏幕截图,可帮助您了解我所面临的问题。

initial state dragging a node and extending the link he same nodes, zoomed out

3 个答案:

答案 0 :(得分:1)

您可能正在寻找CATiledLayer。平铺图层只绘制屏幕上需要渲染的部分,这使得它们非常适合可能对屏幕来说太大或者要进行缩放的视图。它们是呈现UIWebView等视图的核心。

要切换视图以使用平铺图层,您只需声明此方法:

+ (Class)layerClass
{
    return [CATiledLayer class];
}

然后,您将开始看到drawRect:的来电,其值为(0, 0, 256, 256)(0, 256, 256, 256) ......

当移动物品时,您可以通过拨打setNeedsDisplayInRect:而不是setNeedsDisplay来获得额外的性能提升。这将限制绘制到无效的rect。

答案 1 :(得分:1)

  

在哪种情况下,drawRect没有收到UIView的完整帧?

您的绘图实现应始终准备好绘制视图的一部分。对于某些任务,默认剪辑是好的。

只需遵循视图失效过程 - 如果使rect无效,则视图系统遍历视图并要求它们绘制该rect中的内容(考虑不透明度等)。这个矩形可能是(由一组rects组成),但也可能被系统剪掉。

所以你可能正在透支或做多余的绘图 - 考虑如何减少。对于初学者,您可能希望将所有绳索放在一个视图中,并尽一切可能最小化不透明的表面。之后,您应该确定您在哪里透支。 Quartz Debug可以指出这些冗余绘制。您应该使用setNeedsDisplayInRect:而不是setNeedsDisplay,尤其是在绘图时间至关重要的情况下。

答案 2 :(得分:0)

它始终是完整的矩形。那么使用CAShapeLayer呢?

类似的东西:

CAShapeLayer * link = [ CAShapeLayer layer ] ;
link.strokeColor = [ [ UIColor greenColor ] CGColor ] ;

CGMutablePathRef p = CGPathCreateMutable() ;
CGPathMoveToPoint( p, NULL, start ) ;
CGPathAddLineToPoint( p, NULL, end ) ;
link.path = path ;

[ parentView.layer addSublayer:link ] ;