1

I'm trying to do a UIView category for drawing inside drawRect: method without subclassing. To do this, I created a block to simplify this task.

Here's the code:

UIView+DrawRectBlock.h

#import <UIKit/UIKit.h>

// DrawRect block
typedef void(^DrawRectBlock)(UIView *drawRectView, CGRect rect);

@interface UIView (DrawRectBlock)

- (void)drawInside:(DrawRectBlock)block;

@end

UIView+DrawRectBlock.m

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

@interface UIView ()

#pragma mark - Private properties
@property DrawRectBlock drawBlock;

@end

@implementation UIView (DrawRectBlock)

- (void)drawInside:(DrawRectBlock)block {
    if ((self.drawBlock = [block copy])) {
        [self setNeedsDisplay];
    }
}

- (void)drawRect:(CGRect)rect {
    if (self.drawBlock) {
        self.drawBlock(self, rect);
    }
}

- (void)dealloc {
    self.drawBlock = nil;
}

#pragma mark - Others
- (void)setDrawBlock:(DrawRectBlock)drawBlock {
    objc_setAssociatedObject(self, @"block", drawBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (DrawRectBlock)drawBlock {
    return objc_getAssociatedObject(self, @"block");
}

@end

Finally, I call block as follows:

[_testView drawInside:^(UIView *drawRectView, CGRect rect) {

        NSLog(@"DrawReeeeeeect!!!!");

        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextSetLineWidth(context, 5.0);
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, 0.0, 0.0); //start at this point
        CGContextAddLineToPoint(context, 100.0, 100.0); //draw to this point
        CGContextStrokePath(context);

    }];

But "drawRect:" is never called. Any idea?

Thanks!!

mhergon
  • 1,688
  • 1
  • 18
  • 39
  • One question: Why not subclass? – zaph Feb 25 '14 at 23:33
  • It's an experiment, but subclass requires "addSubview:" and wouldn't be possible use with Interface Builder. I need the maximum freedom – mhergon Feb 25 '14 at 23:40
  • Take a browse through http://stackoverflow.com/questions/5272451/overriding-methods-using-categories-in-objective-c to start (TLDR you're just going to cause yourself problems) – Wain Feb 25 '14 at 23:44
  • I have explained it badly. For example, if I have a UITableView and I want draw a simple vertical line, it's a bit cumbersome do a subclass for every UITAbleView on a view. If this method works, it would be ideal to draw quickly and not have lots of subclasses. – mhergon Feb 25 '14 at 23:47
  • Method swizzling doesn't work :( Any other idea? – mhergon Feb 26 '14 at 00:02

1 Answers1

1

Finally I made a mix of subclass and category and works great! https://github.com/mhergon/SimpleBlockDrawing

mhergon
  • 1,688
  • 1
  • 18
  • 39