Skip to content

Instantly share code, notes, and snippets.

@imhuntingwabbits
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save imhuntingwabbits/203b4167894c41db5219 to your computer and use it in GitHub Desktop.
Save imhuntingwabbits/203b4167894c41db5219 to your computer and use it in GitHub Desktop.
Exploring -drawRect:
- (void)drawRect:(CGRect)rect {
UIBezierPath *p = [[UIBezierPath alloc] init];
CGPoint point = [_points objectAtIndex:0];
[p moveToPoint:point];
for (NSValue *v in _points) {
point = [v CGPointValue];
[p addLineToPoint:point];
}
[p setLineWidth:1.0f];
[_lineColor setStroke];
[p stroke];
}
Feb 13 10:09:17 Codemonkey.local Wealthfront[26532] <Error>: CGContextSaveGState: invalid context 0x0.
This is a serious error. This application, or a library it uses, is using an invalid context
and is thereby contributing to an overall degradation of system stability and reliability.
This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.
- (void)testDrawRect {
WFLineChartView *v = [[WFLineChartView alloc] initWithFrame:CGRectMake(0, 0, 99.0f, 99.0f)];
[v drawRect:v.bounds];
}
#define WFAssertPathElementMatchesElement(EXPECTED, ACTUAL) STAssertTrue([EXPECTED isEqual:ACTUAL], @"Element mismatch:\n%@\n%@", EXPECTED, ACTUAL)
#define WFAssertPathElementsMatchElements(EXPECTED, ACTUAL) \
({ \
STAssertTrue([EXPECTED isKindOfClass:[NSArray class]], @"EXPECTED must be an NSArray: %@", EXPECTED); \
STAssertTrue([ACTUAL isKindOfClass:[NSArray class]], @"ACTUAL must be an NSArray: %@", ACTUAL); \
STAssertTrue(EXPECTED.count == ACTUAL.count, @"Wrong number of elements: %lu / %lu", (unsigned long)EXPECTED.count, (unsigned long)ACTUAL.count); \
for (NSUInteger i=0; i < EXPECTED.count; i++) { \
WFAssertPathElementMatchesElement([EXPECTED objectAtIndex:i], [ACTUAL objectAtIndex:i]); \
} \
})
(lldb) po 0xe3bce30
<UIBezierPath: 0xe3bce30; <MoveTo {0, 84}>,
<LineTo {11, 76.333328}>,
<LineTo {22, 68.666672}>,
<LineTo {33, 61}>,
<LineTo {44, 53.333336}>,
<LineTo {55, 45.666668}>,
<LineTo {66, 38}>,
<LineTo {77, 30.333336}>,
<LineTo {88, 22.666668}>,
<LineTo {99, 15}>,
<LineTo {99, 99}>,
<LineTo {0, 99}>,
<LineTo {0, 84}>
(lldb)
- (void)testDrawRect {
/* (lldb) po 0xe3bce30
<UIBezierPath: 0xe3bce30; <MoveTo {0, 84}>,
<LineTo {11, 76.333328}>,
<LineTo {22, 68.666672}>,
<LineTo {33, 61}>,
<LineTo {44, 53.333336}>,
<LineTo {55, 45.666668}>,
<LineTo {66, 38}>,
<LineTo {77, 30.333336}>,
<LineTo {88, 22.666668}>,
<LineTo {99, 15}>,
<LineTo {99, 99}>,
<LineTo {0, 99}>,
<LineTo {0, 84}>
(lldb)
*/
NSArray *elements = [WFTestUtils createArrayOfElementsInPath:_paths[0]];
NSArray *expectedElements = @[[WFCGPathElement pathElementWithType:kCGPathElementMoveToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(0.0f, 84.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(11.0f, 76.333328f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(22.0f, 68.666672f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(33.0f, 61.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(44.0f, 53.333336f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(55.0f, 45.666668f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(66.0f, 38.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(77.0f, 30.333336f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(88.0f, 22.666668f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(99.0f, 15.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(99.0f, 99.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(0.0f, 99.0f)]]],
[WFCGPathElement pathElementWithType:kCGPathElementAddLineToPoint
points:@[[NSValue valueWithCGPoint:CGPointMake(0.0f, 84.0f)]]],
];
WFAssertPathElementsMatchElements(expectedElements, elements);
}
@implementation WFLineChartView
- (UIBezierPath *)createBezierPath {
return [[UIBezierPath alloc] init];
}
@end
@implementation WFLineChartViewTest
- (UIBezierPath *)fakeCreatePath {
UIBezierPath *p = [[UIBezierPath alloc] init];
[_paths addObject:p];
return p;
}
- (void)testDrawRect {
WFLineChartView *v = [[WFLineChartView alloc] initWithFrame:CGRectMake(0, 0, 99.0f, 99.0f)];
id mockV = [OCMockObject partialMockForObject:v];
[[[mockV expect] andCall:@selector(fakeCreatePath) onObject:self] createBezierPath];
[mockV verify];
}
@end
Test Suite 'WFLineChartViewTest' started at 2014-02-14 00:41:48 +0000
Test Case '-[WFLineChartViewTest testDrawRect]' started.
Test Case '-[WFLineChartViewTest testDrawRect]' passed (0.003 seconds).
Test Suite 'WFLineChartViewTest' finished at 2014-02-14 00:41:48 +0000.
@interface WFCGPathElement : NSObject
@property(nonatomic, readonly) CGPathElementType type;
@property(nonatomic, readonly) NSArray *points;
- (instancetype)initWithElement:(const CGPathElement *)element;
@end
/**
Iterate through the paths and create WFCGPathPoint objects.
*/
void WFCGPathApplierFunc(void *info, const CGPathElement *element) {
NSMutableArray *points = (__bridge NSMutableArray *)info;
WFCGPathElement *e = [[WFCGPathElement alloc] initWithElement:element];
[points addObject:e];
}
@implementation WFTestUtils
+ (NSArray *)createArrayOfElementsInPath:(UIBezierPath *)path {
NSMutableArray *points = [NSMutableArray new];
CGPathRef cgp = path.CGPath;
CGPathApply(cgp, (__bridge void *)(points), WFCGPathApplierFunc);
return points;
}
@end
- (void)testDrawRect {
WFLineChartView *v = [[WFLineChartView alloc] initWithFrame:CGRectMake(0, 0, 99.0f, 99.0f)];
CGFloat scaleFactor = [[UIScreen mainScreen] scale];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGRect bounds = view.bounds;
CGContextRef context = CGBitmapContextCreate(NULL,
bounds.size.width * scaleFactor,
bounds.size.height * scaleFactor,
8,
bounds.size.width * scaleFactor * 4,
colorSpace,
(CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
UIGraphicsPushContext(context);
[view drawRect:bounds];
UIGraphicsPopContext();
CFRelease(colorSpace);
CFRelease(context);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment