2009-10-11 85 views
10

所以,我有一个自定义的UIView子类,可以绘制圆角边缘。尽管画面完美,但背景始终充满整个边界,尽管首先剪裁到一条路径。尽管事实上我在drawRect中绘制了边框:在背景之前,边框还在上方绘制了矩形背景。所以我删除了现在几乎为空的drawRect的全部内容:但是背景被绘制了!尽管完全为空drawRect,UIView子类仍然绘制背景: - 为什么?

有人对此有解释吗?我在Interface Builder中设置了backgroundColor。谢谢!

+0

这可能是您的绘图代码的问题。你可以发布它,让我们可以看看?我的猜测是,你正在以某种方式绘制某个地方,要么忽略alpha值,要么在你认为你绘制的东西上绘制了不透明的东西。另外,为了确保,当你设置'backgroundColor'你有适当的alpha设置? – 2009-10-11 18:14:22

+0

嗯,我可以发布我的drawRect :,但正如我所说,它是完全空的:

 - (void) drawRect:(CGRect)rect { } 
Alpha设置在IB中,并且它可以绘制到我设置的任何颜色,无论使用哪个alpha。 我认为必须有一些内在的事情,但是没有新的超级视图,也没有可以绘制背景的子视图。此外,视图图层的backgroundColor为零。 – Pascal 2009-10-11 19:03:52

回答

20

对不起,这个独白。 :)

事情是,UIView的图层显然绘制背景,这是独立于drawRect:。这就是为什么你无法通过覆盖drawRect:摆脱背景。

您可以覆盖- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx做出任何你想要的图层绘制,或重写- (void) setBackgroundColor:(UIColor *)newColor并没有分配newColor的backgroundColor,而是你自己的伊娃,像myBackgroundColor。然后你可以在drawRect中使用myBackgroundColor;不管你喜欢如何绘制背景。


重写setBackgroundColor:

定义一个实例变量来保存你的背景颜色,例如myBackgroundColor。在你的init方法,建立真正的背景色是clearColor:

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    if ((self = [super init...])) { 
     [super setBackgroundColor:[UIColor clearColor]]; 
    } 
    return self; 
} 

覆盖:

- (void) setBackgroundColor:(UIColor *)newColor 
{ 
    if (newColor != myBackgroundColor) { 
     [myBackgroundColor release]; 
     myBackgroundColor = [newColor retain]; 
    } 
} 

然后使用myBackgroundColor在您的drawRect:方法。这样,您可以使用代码中由Interface Builder(或Xcode4)分配的颜色。

0

这是容易复制:

创建一个新的基于视图的iPhone应用程序。创建一个UIView子类,并将drawRect:方法完全清空。在Interface Builder中,将UIView拖入主视图中,为其分配背景颜色并将视图的类设置为您的子类。保存,构建并运行,并查看该视图显示背景颜色。

我已通过覆盖setBackgroundColor规避了此行为:并将颜色分配给我自己的伊娃,始终保留backgroundColor属性nil。这工作,但我仍然想知道为什么这样工作。

6

我毫不犹豫地提出这个建议,因为我不想冒犯你,但你有没有设置为不透明的NO?

+1

没有冒犯,这个问题实际上是一个好问题:是的,不透明被设置为NO。 :) – Pascal 2010-01-12 11:12:39

+0

有时就是这么简单......谢谢! – 2014-04-07 21:47:35

8

这里有一个更简单的解决办法:

self.backgroundColor = [UIColor clearColor]; 
+0

是的,这是通过覆盖setBackgroundColor:来完成的。我更想知道为什么会有任何东西被吸引,尽管drawRect:是空的。回答是,背景绘制在drawLayer:inContext :. – Pascal 2010-03-18 23:18:46

0

您应该设置

clearsContextBeforeDrawing = NO 

就这么简单。

UIView Reference Docs

哎呀。我误解了这个问题。 OP(原始海报)希望他们的自定义控件支持标准的“backgroundColor”属性(例如,由gui designer设置),但不希望系统绘制该颜色。 OP想要自己画bg,以便他能绕过角落。

在这种情况下,关于覆盖层级图的帖子是正确的。

我发布的解决方案将阻止UI系统在绘制之前清除缓冲区。如果没有定义bg,如果设置了clearsContextBeforeDrawing,则iOS将清除视图的缓冲区,将所有像素设置为透明黑色。这样做的全屏视图需要5毫秒左右的iPad3,所以它不是免费的(推动2048x1536像素永远不会)。为了进行比较,绘制全屏位图(使用kCGBlendModeCopy强制blitting)需要约25ms(使用石英,而不是GPU)。

+0

这并不妨碍backgroundColor被绘制;至少不是我的快速测试。 – Pascal 2012-07-30 04:07:39

+0

如果您未设置backgroundColor,会发生什么情况? – 2012-07-30 20:32:01

+0

然后,它的作品,这就是为什么我选择重写'setBackgroundColor:'超级没有设置颜色,并将背景颜色保存到我自己的伊娃。通过这种方式,在我的自定义'drawRect:'中使用了界面构建器中分配的背景颜色,我不必在代码中处理这个。 :) – Pascal 2012-07-31 13:58:32

相关问题