iOS - 包含父/子视图的Quartz绘图问题

时间:2016-05-20 18:15:54

标签: ios objective-c quartz-2d

方案

我有两个观点。一个是“父”视图,其中包含执行绘图的“子”视图。我在后面的代码中将孩子称为QuartzView。 QuartzView知道如何在它自己的上下文中绘制一个正方形。

问题

当我告诉它的self上的QuartzView绘制正方形时,它按预期方式执行。当我使用父视图告诉QuartsView在它的self上绘制一个正方形时,它会在屏幕左下角绘制正方形,大约是预期大小的1/5。

问题

我认为这里有一些父/子或上下文问题,但我不确定它们是什么。如何在完全相同的尺寸下将两个正方形绘制在完全相同的位置?

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);
}

注意

  • 两个方块的不透明度相同
  • 我关闭了“自动调整子视图”,没有明显的差异
  • view.contentScaleFactor = [[UIScreen mainScreen] scale];没有帮助

修改

我注意到从左下角开始绘制父项的正方形的x / y值为0,0而通常0,0将是左上角。

2 个答案:

答案 0 :(得分:2)

  

我假设这里有一些父/子或上下文问题,但我不确定它们是什么。如何在完全相同的尺寸下将两个正方形绘制在完全相同的位置?

您通常不需要担心-drawRect:方法中的图形上下文,因为Cocoa Touch会在调用-drawRect:之前为您设置上下文。但是,视图控制器中的-drawASquare方法会调用-drawRectWithCenter:...在正常绘制过程之外绘制,因此不会为您的视图设置上下文。你应该让视图在-drawRect:中进行绘制。如果视图控制器想要重绘视图,则应调用-setNeedsDisplay,如:

[qv setNeedsDisplay];

这会将视图添加到绘图列表中,图形系统将设置图形上下文并为您调用视图-drawRect:

  

我注意到从左下角开始绘制父项的正方形的x / y值为0,0而通常0,0将是左上角。

UIKit和Core Animation使用左上角原点,但Core Graphics(a.k.a。Quartz)通常使用左下角原点。文档说:

The default coordinate system used by Core Graphics framework is LLO-based.

答案 1 :(得分:2)

UIGraphicsGetCurrentContext()的返回值仅在drawRect方法内有效。您不能也不能在任何其他方法中使用该上下文。所以self.context属性应该只是一个局部变量。

drawRectWithCenter方法中,您应该将所有参数存储在属性中,然后使用[self setNeedsDisplay]请求视图更新。这样,框架将使用新信息调用drawRectdrawRectWithCenter方法看起来应该是这样的

- (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];
}

当然,drawRect函数需要获取该信息,并进行适当的绘制。