The image view being the subview draws on top of the holder view. The imageview is opaque. This means that when the views are drawn there is no part of the holder view that is actually visible, so it's drawRect
call is optimised out.
Try ordering the views the other way around, so that the holder view is the subview of the imageview. Then the imageview will draw and the holder view will draw on top of it.
Also, note that you should use the bounds of the parent view as the frame of the subview.
UIView* subview = [[UIView alloc] initWithFrame:[parentview bounds]];
Edit (add):
See http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html%23//apple_ref/doc/uid/TP40009503-CH2-SW1
, specifically under the section "View Hierarchies and Subview Management":
"Visually, the content of a subview obscures all or part of the content of its parent view"
So, try make the imageview the parent, do your initialisation like so:
// instance variables:
UIImageView* imageView;
MyHolderView* holderView;
imageView = [[UIImageView alloc] initWithFrame:mainRect];
holderView = [[MyHolderView alloc] initWithFrame:[imageView bounds]];
holderView.opaque = NO;
holderView.backgroundColor = [UIColor clearColor];
[imageView addSubview:holderView];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:holderView action:@selector(scale:)];
[pinchRecognizer setDelegate:self];
[holderView addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];
// etc...
Now, the image view is drawn, and the holder view, its subview is drawn on top of it. Now when you call setNeedsDisplay on the holderview it will receive a drawRect:
call.
For example, track the gesture like so. This could be in your view controller or in your MyHolderView view subclass; the example here would be in the MyHolderView class so that the location1
and location2
instance variables can be shared easily with the drawRect:
method.:
-(void)scale:(id)sender {
if (sender == pinchRecognizer) { // this allows the responder to work with multiple gestures if required
// get position of touches, for example:
NSUInteger num_touches = [pinchRecognizer numberOfTouches];
// save locations to some instance variables, like `CGPoint location1, location2;`
if (num_touches >= 1) {
location1 = [pinchRecognizer locationOfTouch:0 inView:holderView];
}
if (num_touches >= 2) {
location2 = [pinchRecognizer locationOfTouch:1 inView:holderView];
}
// tell the view to redraw.
[holderView setNeedsDisplay];
}
}
and then in the holder view drawRect routine:
-(void)drawRect:(CGRect)rect {
// use instance variables location1 and location2 to draw the line.
}