Как я мог обмануть [CALayer renderInContext:], чтобы отобразить только часть слоя?
Я хорошо знаю, что нет никакого хорошего способа сделать небольшую часть UIView для изображения, кроме того, чтобы отобразить весь вид и обрезку. (ОЧЕНЬ дорогой на чем-то вроде iPad 3, где получилось огромное изображение). См. здесь для описания метода renderInContext (нет альтернатив).
Часть представления, которую я хочу отобразить, не может быть предопределена, что означает, что я не могу настроить иерархию представления для маленького раздела как своего собственного UIView (и, следовательно, CALayer).
Моя идея...
У меня была идея, но мне нужно какое-то направление, если я собираюсь добиться успеха. Что делать, если я создаю категорию в UIView (или CALayer), которая добавляет метод по строкам:
[UIView renderSubframe:(CGFrame)frame];
Как? Ну, я думаю, что если бы фиктивный взгляд на размер подкадра был создан, тогда представление можно было временно переключить на это. Затем слой фиктивного представления может вызвать renderInContext:, что приводит к эффективному и быстрому способу получения представлений.
Итак...
Я действительно не настолько, чтобы ускориться с CALayer/Quartz core stuff... Будет ли это иметь какие-либо шансы работать? Если нет, то каким другим способом я мог бы достичь одного и того же, что наиболее эффективным способом я мог бы достичь того же результата (или кто-то еще столкнулся с этой проблемой и придумал другое решение)?
Ответы
Ответ 1
Здесь категория, в которую я закончила писать. Не так сложно, как я думал, благодаря удобному CGAffineTransform.
#import "UIView+RenderSubframe.h"
#import <QuartzCore/QuartzCore.h>
@implementation UIView (RenderSubframe)
- (UIImage *) renderWithBounds:(CGRect)frame {
CGSize imageSize = frame.size;
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y));
[self.layer renderInContext:c];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenshot;
}
@end
Ответ 2
Несколько различных способов сделать это:
setNeedsDisplayInRect:
Отмечает область в указанном прямоугольнике, которая нуждается в обновлении.
- (void)setNeedsDisplayInRect:(CGRect)theRect
Это сделает рендеринг только в указанном прямоугольнике. Я не уверен, будет ли это работать согласно вашему требованию.
Я думаю, что первый вариант должен работать без проблем.