UIView覆盖drawRect导致视图不服从掩码ToBounds

问题描述:

我想覆盖我的自定义视图中的UIView的drawRect:方法。然而,我的观点已经边框半径定义为:UIView覆盖drawRect导致视图不服从掩码ToBounds

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; 

这完美的作品,并把一个漂亮的边框周围我的观点边框半径(不介意对角/直白线在后面,他们没有与该视图做):

correct one

然而,当我尝试重写drawRect:方法在我看来,我可以看到一个黑色的背景不遮蔽到边界。我没有做任何事情(目前),这里是我的代码:

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

这里是结果:

incorrect one

我改变什么,但平局方法。我怎样才能重写绘制方法,同时保持我的视图服从角圆角掩模?这是iOS中的错误还是我错过了一些东西?

我不知道完整的答案,但我知道,根据您是否实施了drawRect:或者没有,UIView的drawLayer:inContext:的实现工作方式不同。也许掩盖/剪裁到边界是它做不同的事情之一。

您可以尝试解决您的问题的一些方法:

  • 让你的背景透明:

    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); 
    

我偷了那最后2项建议从这个伟大的表现从2010年WWDC:Advanced Performance Optimization on iPhone OS(在this index page视频上市 - 烦人的,没有直接的联系)。

也许你不应该叫

[super drawRect:rect] 

您的drawRect内。 Apple says是:

如果直接继承的UIView,实现此方法 不需要调用超。但是,如果您要继承不同的视图类,则应该在您的 实施中的某个时刻调用super。

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

这是一个老问题,但我最近在阅读一篇有用的博客文章,标题为Abusing UIView。在这篇文章中,作者建议不要覆盖drawRect做一些事情,比如在有其他方式的时候添加边框。他说,

覆盖drawRect:导致性能下降。我还没有分析它,所以我不知道它是否在正常的 情况下(这可能不是),但是在大多数情况下,012xx覆盖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; 

我意识到这可能不能解决显示了穿过黑色背景的问题。这只是别的想法。

在视图设置

opaque = false // NO for ObjC 

解决了这个问题。

+0

这是正确的答案。 – Randy