@Till's approach of Method Swizzling is how you achieve this. Mike Ash has one of the better write-ups of how to do it. I currently favor his Direct Override approach, though I've reworked it a little as follows:
#import <objc/runtime.h>
@interface NSObject (RNSwizzle)
+ (IMP)swizzleSelector:(SEL)origSelector withIMP:(IMP)newIMP;
@end
@implementation NSObject (RNSwizzle)
+ (IMP)swizzleSelector:(SEL)origSelector withIMP:(IMP)newIMP {
Class class = [self class];
Method origMethod = class_getInstanceMethod(class, origSelector);
IMP origIMP = method_getImplementation(origMethod);
if(!class_addMethod(self, origSelector, newIMP,
method_getTypeEncoding(origMethod)))
{
method_setImplementation(origMethod, newIMP);
}
return origIMP;
}
@end
Given his example, you would use my method this way:
gOrigDrawRect = [UIView swizzleSelector:@selector(drawRect:)
withIMP:OverrideDrawRect];
These are all documented calls and do not make use of Apple private APIs. Apple does sometimes reject apps that make too dramatic a change to expected UI behaviors (regardless of how they do it), but I've shipped stuff with pretty dramatic under-the-covers UI modifications without trouble, and this does not rely on private APIs.
That doesn't mean that Method Swizzling is stable. It's a fragile technique and does make you more reliant on undocumented internals. It may mean you have to scramble more if Apple changes something.
(Deep breath)
There's another approach you can use here, as long as you require no ivar storage. You can grab the scroll view and class swizzle it to your own subclass. Did I mention you must have no ivar storage of your own? The bugs you'll create if you allocate an ivar in this and mind-bending. Deusty writes this up well in his blog. (It was his code that I added an ivar to and encountered the incredibly mind-bending bugs mentioned above.)
Again, this is a fragile, crazy, dangerous technique. It also can sometimes be the most elegant and maintainable way to do what you need.