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);
}
Примечание
- непрозрачности одинаковы для обоих квадратов
- я выключил "подпанелей автоматического изменения размеров" без заметного разница
-
view.contentScaleFactor = [[UIScreen mainScreen] scale];
не помогло
Edit
Я замечаю, что значения x/y квадрата при рисовании родителя начинаются с нижнего левого угла как 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
должна возьмите эту информацию и сделайте соответствующий рисунок.
Я предполагаю, что здесь есть некоторые проблемы родителя/ребенка или контекста, но я не уверен, что они есть. Как я могу заставить оба квадрата рисовать в одном и том же месте с одинаковым размером?Обычно вам не нужно беспокоиться о графическом контексте в вашем методе-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) обычно использует нижний левый источник. В документах говорится:
система координат по умолчанию, используемая Core Graphics framework, основана на LLO.