UIView's drawRect not being called when swizzled

core-graphics, drawrect, ios, objective-c, swizzling

Solution

First, read to drawRect or not to drawRect (when should one use drawRect/Core Graphics vs subviews/images and why?)

Basically, `UIView` checks if you override `drawRect:` or not. If you don't override it, it can do lots of drawing optimizations and the method won't be even called.

In this case you didn't override it so `UIView` sees no reason to call it, even if you replaced the empty implementation with something else.

Problem

I am experimenting with advanced Objective-C methods. What I want to achieve is to append specific drawing code to an existing `UIView`. I started easily, I went on to declare my own `drawRect` method in a category: ``` @interface UIView (Swizzled) - (void)my_drawRect:(CGRect)rect; @end ``` Then I swizzled the `drawRect` method of `UIView` in the implementation of the category: ``` + (void)load { [self swizzleInstanceMethod:@selector(drawRect:) withMethod:@selector(my_drawRect:) inClass:[UIView class]]; } - (void)my_drawRect:(CGRect)rect { NSLog (@"Test."); } ``` Implementation of this method is available on GitHub and the swizzling works in all other cases. So according to the logic, every time `drawRect` is called, it should just print out "Test". But it does not work, the method I swizzled is never called. I went on to discover what I did wrong here, but the more I look at it, the more I believe the problem is somewhere else. What if the `drawRect` method is not even called? I went on to try to force it being called: ``` view.contentMode = UIViewContentModeRedraw; [view setNeedsDisplay]; ``` Doesn't work either. So my question is: How to force `UIView` to call `drawRect` in this case or even my swizzled implementation? Thanks!

Original source

Related problems