Scenario
I have two views. One is the "parent" view which contains a "child" view that does the drawing. I refer to the child as QuartzView in the code to follow. QuartzView knows how to draw a square to it's own context.
Issue
When I tell the QuartzView on it's self
to draw a square it does so as expected. When I use the parent view to tell QuartsView to draw a square on it's self
it draws the square in the lower left corner of the screen at about 1/5 the expected size.
Question
I assume there's some parent/child or context issues here but I'm not sure what they are. How can I get both squares to draw in the exact same place at the exact same size?
ViewController
- (void)drawASquare {
// this code draws the "goofy" square that is smaller and off in the bottom left corner
x = qv.frame.size.width / 2;
y = qv.frame.size.height / 2;
CGPoint center = CGPointMake(x, y);
[qv drawRectWithCenter:center andWidth:50 andHeight:50 andFillColor:[UIColor blueColor]];
}
QuartzView
- (void)drawRect:(CGRect)rect
{
self.context = UIGraphicsGetCurrentContext();
UIColor *color = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.5];
// this code draws a square as expected
float w = self.frame.size.width / 2;
float h = self.frame.size.height / 2;
color = [UIColor blueColor];
CGPoint center = CGPointMake(w, h);
[self drawRectWithCenter:center andWidth:20 andHeight:20 andFillColor:color];
}
- (void)drawRectWithCenter:(CGPoint)center andWidth:(float)w andHeight:(float)h andFillColor:(UIColor *)color
{
CGContextSetFillColorWithColor(self.context, color.CGColor);
CGContextSetRGBStrokeColor(self.context, 0.0, 1.0, 0.0, 1);
CGRect rectangle = CGRectMake(center.x - w / 2, center.x - w / 2, w, h);
CGContextFillRect(self.context, rectangle);
CGContextStrokeRect(self.context, rectangle);
}
Note
view.contentScaleFactor = [[UIScreen mainScreen] scale];
has not helped I'm noticing that the x/y values of the square when drawn the parent starting from the bottom left as 0,0 whereas normally 0,0 would be the top left.
I assume there's some parent/child or context issues here but I'm not sure what they are. How can I get both squares to draw in the exact same place at the exact same size?
You normally don't need to worry about the graphics context in your -drawRect:
method because Cocoa Touch will set up the context for you before calling -drawRect:
. But your -drawASquare
method in the view controller calls -drawRectWithCenter:...
to draw outside the normal drawing process, so the context isn't set up for your view. You should really have the view do its drawing in -drawRect:
. If your view controller wants to make the view redraw, it should call -setNeedsDisplay
, like:
[qv setNeedsDisplay];
That will add the view to the drawing list, and the graphics system will set up the graphics context and call the view's -drawRect:
for you.
I'm noticing that the x/y values of the square when drawn the parent starting from the bottom left as 0,0 whereas normally 0,0 would be the top left.
UIKit and Core Animation use an upper left origin, but Core Graphics (aka Quartz) normally uses a lower left origin. The docs say:
The default coordinate system used by Core Graphics framework is LLO-based.
The return value from UIGraphicsGetCurrentContext()
is only valid inside the drawRect
method. You can not and must not use that context in any other method. So the self.context
property should just be a local variable.
In the drawRectWithCenter
method, you should store all of the parameters in properties, and then request a view update with [self setNeedsDisplay]
. That way, the framework will call drawRect
with the new information. The drawRectWithCenter
method should look something like this
- (void)drawRectWithCenter:(CGPoint)center andWidth:(float)w andHeight:(float)h andFillColor:(UIColor *)color
{
self.showCenter = center;
self.showWidth = w;
self.showHeight = h;
self.showFillColor = color;
[self setNeedsDisplay];
}
And of course, the drawRect
function needs to take that information, and do the appropriate drawing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.