【问题标题】:drawRect not being called in my subclass of UIImageView在我的 UIImageView 的子类中没有调用 drawRect
【发布时间】:2011-02-06 09:59:43
【问题描述】:

我已将 UIImageView 子类化并尝试覆盖 drawRect,以便我可以使用 Quartz 2D 在图像顶部进行绘制。我知道这是一个愚蠢的新手问题,但我没有看到我做错了什么。界面如下:

#import <UIKit/UIKit.h>

@interface UIImageViewCustom : UIImageView {

}
- (void)drawRect:(CGRect)rect;
@end

以及实现:

#import "UIImageViewCustom.h"

@implementation UIImageViewCustom

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // do stuff
}

- (void)dealloc {
    [super dealloc];
}
@end

我在drawRect 上设置了一个断点,但它永远不会命中,这让我认为它根本不会被调用。视图首次加载时不应该调用它吗?我是否错误地覆盖了它?

【问题讨论】:

  • 请看更新后的答案,再次打扰您。
  • 好吧。浏览我观察到的文档,如果你创建 UIView 的子类而不是 UIIMageView,它会起作用,现在你可以在你的子类中添加 UIImageView 的属性,我做了一次来绘制我的 tableview 单元格的背景,有关更多详细信息,你可以检查在.stackoverflow.com/questions/1784827/…

标签: iphone objective-c cocoa-touch uikit


【解决方案1】:

只有在视图可见且脏的情况下才会调用它。也许问题出在创建视图的代码中,或者在您的 Nib 中,如果您是这样创建它的?

如果您尝试调试“发布”版本,有时还会看到无法正确设置断点。


我不知何故错过了您第一次将 UIImageView 子类化。来自文档:

特别注意事项

UIImageView 类被优化为 将其图像绘制到显示器上。 UIImageView 不会调用 drawRect: 在 子类。如果您的子类需要 自定义绘图代码,推荐 你使用 UIView 作为基类。

所以你有它。鉴于使用 [UIImage drawInRect:] 或使用 CALayer 将图像绘制到视图中是多么容易,因此可能没有充分的理由将 UIImageView 子类化。

【讨论】:

  • 第一次渲染视图时不应该调用 drawRect 吗?
  • 其实,既然你提到它,我记得读过。不知道为什么我找的时候找不到了。谢谢。
  • UIImageView 如果您想与 IB 一起工作,那么能够进行子类化是一件很棒的事情。叹息......谢谢你的回答,它有帮助。
  • 但是再想想,你仍然可以继承它。你就是不能乱画:)
  • 六年后继续进行,用于 UIImageView 子类化的 Swift 3.0.1/Xcode 8.2.1 模板仍然有样板注释掉 draw(_ rect: CGRect) 函数,其中注释说如果您需要自定义绘图只需取消注释并添加您的自定义绘图代码。所以,谢谢你,stackoverflow 社区!
【解决方案2】:

尝试添加

编辑:

- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self setClearsContextBeforeDrawing:YES];//add this line also
    }
    return self;
}


- (void)setNeedsDisplay{
    [self setNeedsDisplayInRect:self.frame];
}

进入您的代码。

希望这会有所帮助。

谢谢,

疯狂

【讨论】:

    【解决方案3】:

    不直接回答您的问题,但可能会解决您的问题:

    为什么要使用 UIImageView 的子类?子类化总是有问题的,特别是对于那些没有被设计为子类化的类——我敢打赌 UIImageView 不是。如果您只想在图像上绘制东西,则创建一个具有透明背景的视图,绘制您想要的任何内容,然后将其直接放在图像上。

    【讨论】:

    • 好的,很好,我在文档中查找了它,显然子类化它很好。我仍然怀疑这不是实现目标的最佳方式。
    【解决方案4】:

    根据您的具体情况,使用带有背景图像的 UIButton 而不是 UIImageView 可能更有意义。您甚至可以将 userInteractionEnabled 设置为 NO,结果与 UIImageView 无法区分。

    在这种情况下,您的 UIButton 子类将简单地包括:

    - (void)drawRect:(CGRect)rect
    {
      if (kSomethingSpecial) {
        [self setBackgroundImage:[UIImage imageNamed:@"RedBackground.png"] 
                        forState:UIControlStateNormal];
      }
    }
    

    免责声明 - 如果您计划至少在某些时候将图像用作按钮,我只会建议您这样做。我不能全心全意地支持使用UIButton 作为UIImageView 中这种drawRect 行为的解决方法,因为我确信Apple 有其原因以这种方式编写他们的API,就像Mark 所引用的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      相关资源
      最近更新 更多