2016-05-20 8 views
2

СценарийIOS - Кварцевый рисунок проблема с родителем/ребенок рассматривает

У меня есть две точки зрения. Один из них - это «родительский» вид, который содержит «дочерний» вид, который делает рисунок. Я обращаюсь к ребенку как к QuartzView в коде, которому нужно следовать. QuartzView знает, как рисовать квадрат в собственном контексте.

Выпуск

Когда я говорю QuartzView на это self нарисовать квадрат это так, как ожидалось. Когда я использую родительское представление, чтобы сказать 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); 
} 

Примечание

  • непрозрачности одинаковы для обоих квадратов
  • Я выключил «AUTORESIZE подвидов» без заметной разницы
  • view.contentScaleFactor = [[UIScreen mainScreen] scale]; не помог

Редактировать

Я замечаю, что х/у значения квадрата при рисовании родителя, начиная от внизу слева как 0,0, тогда как обычно 0,0 будет верхним левым.

ответ

2

Возвращаемое значение UIGraphicsGetCurrentContext() действует только внутри метода drawRect. Вы не можете и не должны использовать этот контекст в любом другом методе. Таким образом, свойство self.context должно быть локальной переменной.

В методе drawRectWithCenter вы должны сохранить все параметры в свойствах, а затем запросить обновление для просмотра с помощью [self setNeedsDisplay]. Таким образом, структура будет вызывать drawRect с новой информацией. Метод drawRectWithCenter должен выглядеть что-то вроде этого

- (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 должна принять эту информацию, и сделать соответствующий рисунок.

+2

Это хороший момент, который явно не упоминается - не пытайтесь хранить и повторно использовать графический контекст. – Caleb

+1

Первое предложение этого ответа не соответствует действительности, но достаточно близко для этого вопроса. Существуют и другие допустимые места, где 'UIGraphicsGetCurrentContext()' может быть действительным. Но ОП не использует ни одну из этих ситуаций. – rmaddy

+0

@rmaddy достаточно справедливо. Это похоже на то, что вы не можете взять квадратный корень из отрицательного числа. В конце концов, студент готов понять более сложные концепции, но изначально лучше всего держать его простым. – user3386109

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.

+0

Это, безусловно, новая информация, но она до сих пор меня достала. Поскольку один и тот же метод из одного представления используется оба раза, почему один квадрат выведен на UIKit, а другой - на Quartz? – Jacksonkr

+1

@Jacksonkr Поскольку контекст настраивается только при вызове '-drawRect:'. Я нажал кнопку отправки немного раньше, обновил свой ответ. См. Выше. – Caleb