Wednesday, June 1, 2011

an example of method swizzling by customizing an UINavigationBar

an example of method swizzling by customizing an UINavigationBar

  • /*  * Some references:  *     http://www.cocoadev.com/index.pl?MethodSwizzling  *     http://samsoff.es/posts/customize-uikit-with-method-swizzling  *     http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1  *     http://developer.apple.com/iphone/library/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html  *     http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html  *     http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html  *  */   /* UINavigationBar+Additions.h */ #import   @interface UINavigationBar (Additions)  - (void)drawRectCustom:(CGRect)rect;  @end   /* UINavigationBar+Additions.m */ #import "UINavigationBar+Additions.h"   @implementation UINavigationBar (Additions)   // When the object is set up it calls drawRect, which then loads this method because of the method swizzling - (void)drawRectCustom:(CGRect)rect {      // If the style of the bar is the default style, apply our custom visuals     if (self.barStyle == UIBarStyleDefault) {          // Create the drawing context         CGContextRef ctx = UIGraphicsGetCurrentContext();          // Set the background color of the navbar         [[UIColor blackColor] set];         CGRect fillRect = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height);         CGContextFillRect(ctx, fillRect);          // Create an instance of the image we want to draw         UIImage * logo = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"path/to/logo" ofType:@"png"]];          // Get the absolute center points relative to the image and the screen         NSNumber * centerX = [NSNumber numberWithFloat:(self.frame.size.width/2 - logo.size.width/2)];         NSNumber * centerY = [NSNumber numberWithFloat:(self.frame.size.height/2 - logo.size.height/2)];          // Draw the image         [logo drawInRect:CGRectMake(centerX.floatValue, centerY.floatValue, logo.size.width, logo.size.height)];          // End execution of the method         return;     }      // By this time drawRectCustom is actually referencing to drawRect     [self drawRectCustom:rect]; }   @end   /* main.m */ #import  #import  // Needed for the Method objects #import "UINavigationBar+Additions.h" // Needed to reference the method we wish to swizzle  int main(int argc, char *argv[]) {     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];      /* Method Swizzling */      // Get our drawRectCustom method     Method drawRectCustom = class_getInstanceMethod([UINavigationBar class], @selector(drawRectCustom:));      // Get the original drawRect method     Method drawRect = class_getInstanceMethod([UINavigationBar class], @selector(drawRect:));      // Swap the methods, drawRect now becomes drawRectCustom and vice-versa     method_exchangeImplementations(drawRect, drawRectCustom);      /* End Method Swizzling */      int retVal = UIApplicationMain(argc, argv, nil, nil);      [pool release];     return (retVal); }   @end 

No comments: