web-dev-qa-db-ja.com

UIImageViewのサブクラスでdrawRectが呼び出されない

Quartz 2Dを使用して画像の上に描画できるように、UIImageViewをサブクラス化してdrawRectをオーバーライドしようとしました。私はこれが馬鹿げた初心者の質問であることを知っていますが、私が間違ったことを私は見ていません。インターフェースは次のとおりです。

#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にブレークポイントを設定しましたが、ヒットしなかったため、まったく呼び出されないと思いました。ビューが最初にロードされたときに呼び出されるはずではありませんか?誤って上書きしてしまいましたか?

42
Ben Collins

ビューが表示されていて、ダーティである場合にのみ呼び出されます。たぶん問題はビューを作成するコード、またはそれがあなたがそれを作成している方法である場合、あなたのニブにありますか?

また、「リリース」ビルドをデバッグしようとすると、ブレークポイントが正しく設定されないことがあります。


あなたがUIImageViewをサブクラス化しているのを初めて見逃しました。ドキュメントから:

特別な考慮事項

UIImageViewクラスは、そのイメージをディスプレイに描画するように最適化されています。 UIImageViewは、サブクラスのdrawRect:を呼び出しません。サブクラスでカスタム描画コードが必要な場合は、UIViewを基本クラスとして使用することをお勧めします。

だからあなたはそれを持っています。 [UIImage drawInRect:]を使用して、またはCALayerを使用してビューに画像を描画するのがいかに簡単かを考えると、おそらくUIImageViewをサブクラス化する正当な理由はおそらくありません。

87
Mark Bessey

追加してみてください

編集:

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


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

あなたのコードに。

お役に立てれば。

おかげで、

マダップ

1

特定のケースによっては、UIButtonの代わりに、背景画像とともにUIImageViewを使用することが理にかなっています。 userInteractionEnabledをNOに設定することもでき、結果はUIImageViewと区別できません。

この場合、UIButtonサブクラスには単純に次のものが含まれます。

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

免責事項-少なくともいつかは画像をボタンとして使用する予定がある場合にのみ、これをお勧めします。 AppleにマークのようにAPIをこのように記述する理由があるので、UIButtonでのこのdrawRect動作の回避策としてUIImageViewを使用することを心から推奨することはできません。

0
Kyle Clegg

あなたの質問に直接答えることはできませんが、あなたの問題を解決するかもしれません:

なぜUIImageViewのサブクラスでこれを行うのですか?特にサブクラス化するように設計されていないクラスの場合、サブクラス化は常に問題が発生する可能性があります。UIImageViewはそうではないに違いありません。画像の上にものを描画したいだけの場合は、背景が透明なビューを作成し、必要なものを描画して、画像の上に直接配置します。

0
jasoncrawford