2012-01-11 10 views
0

私自身のdrawRectメソッドを定義し、それは4.2.1(iOS)5.0(iOS)と4.3.2(Simulator)で成功して呼び出されます。しかし、それは3.1.3(iPhone 2g)を呼び出すことはありませんでした。- [UIView(MyOwnCategory)drawRect:]は3.1.3で呼び出されませんでしたか?

これにはどのような理由がありますか?

P.S.私は3.1.3デバイスについてjailbrokenと思う質問を書き始めます。たぶんそれはこの奇妙な行動の根本原因です。

UPD:私は次のコードを使用して問題を再現するには、次の

@implementation UIView (MyOwnCategory) 
- (void)drawRect:(CGRect)rect 
{ 
    const char * function = __FUNCTION__; 
    [NSException raise: @"hi!" format: @"%s", function]; 
} 
@end 

例外は私は今、数週間のための方法スウィズルについて書きたかった

+0

ビューはサブクラスですか?またはdrawRectのカテゴリメソッドですか? – jrtc27

+0

iPhone 2Gを接続します。 Xcodeにブレークポイントを設定します。コード行にヒットしますか?あなたがそれをしている間、あなたはいくつかのコードを表示できますか? –

+6

なぜ '-drawRect:'を 'UIView'のカテゴリに実装していますか?それは本当に悪い考えのように思えます。 –

答えて

3

明示的[super drawRect: rect]を呼び出す場合でも、3.1.3に起こったことはありません@ケビン・バラードのコメントが私にしました(インスピレーションのために感謝、ケビン)。

のUIView + Border.h:

#import <Foundation/Foundation.h> 
@interface UIView(Border) 
@end 

のUIView + Border.m:

だからここにものiOS 3.xの上で動作するはずmethod swizzlingを使用して、問題の解決策だ

#import "UIView+Border.h" 
#import <QuartzCore/QuartzCore.h> 
#import <objc/runtime.h> 

@implementation UIView(Border) 

- (id)swizzled_initWithFrame:(CGRect)frame 
{ 
    // This is the confusing part (article explains this line). 
    id result = [self swizzled_initWithFrame:frame]; 

    // Safe guard: do we have an UIView (or something that has a layer)? 
    if ([result respondsToSelector:@selector(layer)]) { 
     // Get layer for this view. 
     CALayer *layer = [result layer]; 
     // Set border on layer. 
     layer.borderWidth = 2; 
     layer.borderColor = [[UIColor redColor] CGColor]; 
    } 

    // Return the modified view. 
    return result; 
} 

- (id)swizzled_initWithCoder:(NSCoder *)aDecoder 
{ 
    // This is the confusing part (article explains this line). 
    id result = [self swizzled_initWithCoder:aDecoder]; 

    // Safe guard: do we have an UIView (or something that has a layer)? 
    if ([result respondsToSelector:@selector(layer)]) { 
     // Get layer for this view. 
     CALayer *layer = [result layer]; 
     // Set border on layer. 
     layer.borderWidth = 2; 
     layer.borderColor = [[UIColor blueColor] CGColor]; 
    } 

    // Return the modified view. 
    return result; 
} 

+ (void)load 
{ 
    // The "+ load" method is called once, very early in the application life-cycle. 
    // It's called even before the "main" function is called. Beware: there's no 
    // autorelease pool at this point, so avoid Objective-C calls. 
    Method original, swizzle; 

    // Get the "- (id)initWithFrame:" method. 
    original = class_getInstanceMethod(self, @selector(initWithFrame:)); 
    // Get the "- (id)swizzled_initWithFrame:" method. 
    swizzle = class_getInstanceMethod(self, @selector(swizzled_initWithFrame:)); 
    // Swap their implementations. 
    method_exchangeImplementations(original, swizzle); 

    // Get the "- (id)initWithCoder:" method. 
    original = class_getInstanceMethod(self, @selector(initWithCoder:)); 
    // Get the "- (id)swizzled_initWithCoder:" method. 
    swizzle = class_getInstanceMethod(self, @selector(swizzled_initWithCoder:)); 
    // Swap their implementations. 
    method_exchangeImplementations(original, swizzle); 
} 

@end 
+0

ありがとうございます。このコードは私の願い(ビューを見るため)を解決します。 3.1.3 – Speakus

+1

でdrawRectと呼ばれることはなかったという私の最初の質問には答えませんが、あなたの質問は答えられませんでした。私の推測です:[drawRect:reference](http://developer.apple.com/library/ios/documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/drawRect :)、デフォルトの実装は何もせず、ダイレクト 'UIView'サブクラスで' [super drawRect:bounds];を呼び出す必要はありません。そのため、メソッドが単純なUIViewクラスで呼び出されるという保証はありません(必要はありません)。 – DarkDust

関連する問題