Подтвердить что ты не робот

UIGraphicsGetCurrentContext vs UIGraphicsBeginImageContext/UIGraphicsEndImageContext

Я новичок в этих частях API iOS, и вот некоторые вопросы, которые вызывают у меня бесконечный цикл.

  • Почему..BeginImageContext имеет размер, но..GetCurrentContext не имеет размера? Если..GetCurrentContext не имеет размера, где он рисует? Каковы границы?

  • Почему у них должны быть два контекста: один для изображения и один для общей графики? Разве контекст изображения уже не является графическим контекстом? В чем причина разделения (я пытаюсь понять, чего не знаю)

4b9b3361

Ответ 1

UIGraphicsGetCurrentContext() возвращает ссылку на текущий графический контекст. Это не создает. Это важно помнить, потому что если вы посмотрите на него в этом свете, вы увидите, что ему не нужен параметр размера, потому что текущий контекст - это просто размер, с которым был создан графический контекст.

UIGraphicsBeginImageContext(aSize) предназначен для создания графических контекстов на уровне UIKit за пределами метода UIView drawRect:.

Здесь вы можете использовать их.

Если у вас есть подкласс UIView, вы можете переопределить его метод drawRect: так:

- (void)drawRect:(CGRect)rect
{
    //the graphics context was created for you by UIView
    //you can now perform your custom drawing below

    //this gets you the current graphic context
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    //set the fill color to blue
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);

    //fill your custom view with a blue rect
    CGContextFillRect(ctx, rect);
}

В этом случае вам не нужно было создавать графический контекст. Он был создан для вас автоматически и позволяет выполнять собственный рисунок в методе drawRect:

Теперь, в другой ситуации, вы можете выполнить какой-то пользовательский чертеж вне метода drawRect:. Здесь вы можете использовать UIGraphicsBeginImageContext(aSize)

Вы можете сделать что-то вроде этого:

UIBezierPath *circle = [UIBezierPath
                        bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];  

UIGraphicsBeginImageContext(CGSizeMake(200, 200));

//this gets the graphic context
CGContextRef context = UIGraphicsGetCurrentContext();

//you can stroke and/or fill
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
[circle fill];
[circle stroke];

//now get the image from the context
UIImage *bezierImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

UIImageView *bezierImageView = [[UIImageView alloc]initWithImage:bezierImage];

Надеюсь, это поможет вам разобраться. Кроме того, вы должны использовать UIGraphicsBeginImageContextWithOptions (размер, непрозрачность, масштаб). Для дальнейшего объяснения пользовательского чертежа с графическими контекстами см. Мой ответ здесь

Ответ 2

Здесь вы немного смущены.

Как следует из названия, UIGraphicsGetCurrentContext захватывает контекст CURRENT, поэтому ему не нужен размер, он захватывает контекст существующий и возвращает его вам.

Итак, когда существует существующий контекст? Всегда? Нет. Когда экран отображает кадр, создается контекст. Этот контекст доступен в функции DrawRect:, которая вызывается для рисования представления.

Как правило, ваши функции не вызывается в DrawRect:, поэтому они фактически не имеют контекста. Это когда вы вызываете UIGraphicsBeginImageContext.

Когда вы это сделаете, вы создаете контекст изображения, затем вы можете захватить указанный контекст с помощью UIGraphicsGetCurrentContext и работать с ним. И таким образом, вы должны помнить, чтобы положить конец UIGraphicsEndImageContext

Чтобы прояснить ситуацию - если вы измените контекст в DrawRect:, ваши изменения будут показаны на экране. В вашей собственной функции ваши изменения нигде не отображаются. Вы должны извлечь изображение в контексте через вызов UIGraphicsGetImageFromCurrentImageContext().

Надеюсь, это поможет!