UIView重写drawRect会导致视图不遵守masksToBounds

时间:2012-12-06 15:21:54

标签: ios uiview ios6 drawrect

我试图在自定义视图中覆盖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;

这很有效,并且在我的视图周围放置了一个带边框半径的漂亮边框(不要介意背面的对角线/直线白线,它们与此视图无关):

correct one

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

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

结果如下:

incorrect one

除了绘制方法,我什么都没改变。如何在保持视图遵循角半径蒙版的同时覆盖绘制方法?这是iOS中的错误还是我错过了什么?

4 个答案:

答案 0 :(得分:3)

我不知道完整的答案,但我知道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的这篇精彩演讲中偷走了最后两条建议:Advanced Performance Optimization on iPhone OS(视频列在this index page - 烦人,没有直接链接。)

答案 1 :(得分:2)

这是一个老问题,但我最近在阅读一篇名为Abusing UIView的有用博客文章。在其中,作者建议不要覆盖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;

我意识到这可能无法解决黑色背景显示的问题。这是另一个需要考虑的事情。

答案 2 :(得分:2)

设置

opaque = false // NO for ObjC
视图上的

解决了这个问题。

答案 3 :(得分:1)

可能你不应该打电话给

[super drawRect:rect]

在drawRect中。 Apple says那个:

  

如果直接子类化UIView,则执行此方法   不需要打电话给超级。但是,如果你是一个子类   不同的视图类,你应该在你的某个时刻调用super   实施

似乎调用super方法会导致奇怪的行为。