7

我试图drawRect:在我的自定义视图中覆盖 UIView 的方法。但是,我的视图的边界半径定义为:

    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;

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

正确一个

但是,当我尝试drawRect:在我的视图中覆盖该方法时,我可以看到黑色背景没有遮盖边界。我什么都不做目前),这是我的代码:

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

结果如下:

不正确的

除了draw方法,我什么都没改变。如何在保持视图服从角半径遮罩的同时覆盖 draw 方法?这是iOS中的错误还是我错过了什么?

4

4 回答 4

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 的这个精彩演示文稿中窃取了最后两条建议:iPhone OS 上的高级性能优化(此索引页面上列出的视频——烦人的是,没有直接链接)。

于 2013-04-24T00:56:45.883 回答
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;

我意识到这可能无法解决黑色背景透出的问题。这只是需要考虑的其他事情。

于 2015-06-18T14:51:37.137 回答
2

环境

opaque = false // NO for ObjC

在视图上解决了问题。

于 2016-06-22T09:51:04.977 回答
1

可能你不应该打电话给

[super drawRect:rect]

在你的drawRect里面。苹果表示

如果你直接继承 UIView,你的这个方法的实现不需要调用 super。但是,如果您要对不同的视图类进行子类化,则应在实现中的某个时刻调用 super。

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

于 2014-12-09T14:32:27.413 回答