UIView覆盖drawRect会导致视图不服从masksToBounds

我想重写我的自定义视图中UIView的drawRect:方法。 但是,我的观点有一个边界半径定义为:

  sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0]; [self addSubview:sub]; [sub setUserInteractionEnabled:YES]; [self setUserInteractionEnabled:YES]; CALayer *layer = sub.layer; layer.masksToBounds = YES; layer.borderWidth = 5.0; layer.borderColor = [UIColor whiteColor].CGColor; layer.cornerRadius = 30.0; 

这完美地工作,并在我的视图周围放置一个带有边框半径的漂亮边框(不要介意后面的对angular/直线白线,它们与此视图无关):

正确的一个

但是,当我尝试重写我的视图中的drawRect:方法时,我可以看到一个黑色的背景不掩盖边界。 我没有做任何事情 (目前),这是我的代码:

 -(void)drawRect:(CGRect)rect{ [super drawRect:rect]; } 

结果如下:

不正确的

我只改变了绘制方法。 我怎样才能重写绘制方法,同时保持我的观点服从angular圆angular面具? 这是在iOS的错误,或者我错过了什么?

我不知道完整的答案,但我知道UIView的drawLayer:inContext:的实现取决于你是否实现了drawRect:或者不同。 也许掩盖/裁减边界是其中一个不同的事情之一。

您可以尝试以多种方式解决您的问题:

  • 使您的背景透明:

      layer.backgroundColor = [UIColor clearColor].CGColor; 
  • 将自己夹在自定义的drawRect:

     - (void)drawRect:(CGRect)rect { [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:30.0] addClip]; [image drawInRect:rect]; // or whatever } 
  • 明确指出了这个问题:

     CGContextBeginPath(c); CGContextAddArc(c, r, r, r, M_PI, 3*M_PI_2, 0); CGContextAddLineToPoint(c, 0, 0); CGContextClosePath(c); CGContextClip(c); [[UIColor grayColor] setFill]; UIRectFill(rect); 

我从WWDC 2010这个精彩的演示里偷走了最后两个build议: iPhone OS上的高级性能优化 (video在这个索引页面上列出 – 令人讨厌,没有直接的联系)。

这是一个古老的问题,但我最近正在阅读一篇名为“ 滥用UIView ”的有用博客文章。 在这个例子中,作者build议不要让重写drawRect做一些事情,比如在有其他方法的时候添加边框。 他说,

覆盖drawRect:导致性能下降。 我没有对它进行分析,所以我不知道它在正常情况下是否显着(可能不是),但是在大多数情况下,重写drawRect:人可以通过设置视图图层属性。 如果您需要围绕视图绘制轮廓,请按照以下步骤操作:

 #import <QuartzCore/QuartzCore.h> - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.layer.borderWidth = 2.f; self.layer.borderColor = [UIColor redColor].CGColor; } return self; 

我意识到这可能并没有解决黑色背景显示的问题。 这只是别的想法。

可能你不应该打电话给你

 [super drawRect:rect] 

在你的drawRect里面。 苹果说 :

如果直接inheritanceUIView,则此方法的实现不需要调用super。 但是,如果您inheritance不同的视图类,则应该在实现中的某个位置调用super。

看来,调用超级方法会导致奇怪的行为。

设置

 opaque = false // NO for ObjC 

在视图上解决了这个问题。