2012-01-11 81 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設備已經越獄了。也許這是這種奇怪行爲的根源。

UPD:要重現問題,我使用下面的代碼:

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

例外,從來沒有發生過3.1.3甚至當我打電話[super drawRect: rect]明確

+0

您的視圖是子類還是drawRect類別方法? – jrtc27 2012-01-11 22:33:32

+0

插入你的iPhone 2G。在Xcode中設置斷點。代碼行是否受到影響?也許你可以在看到代碼時顯示一些代碼? – 2012-01-11 22:33:36

+6

你爲什麼要在'UIView'類中實現'-drawRect:'?這聽起來像一個非常糟糕的主意。 – 2012-01-11 22:34:46

回答

3

我現在就想寫寫方法混寫了幾個星期,凱文巴拉德的評論終於讓我做到了(謝謝你的啓發,凱文)。

因此,這裏是使用method swizzling你的問題的解決方案也應在iOS 3.x的工作:

的UIView + Border.h:

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

的UIView + Border.m:

#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 2012-01-12 22:25:40

+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 2012-01-12 23:14:17