Как захватить текущий снимок экрана и повторное использование кода? (iPhone SDK)
Я пытаюсь перейти от одного UIView к другому, когда пользователь поворачивает устройство. Это само по себе не сложно. Однако, поскольку я показываю совершенно другое содержимое после вращения, анимация по умолчанию, предоставляемая UIKit (вращение отображаемого в настоящее время вида), концептуально неприемлема.
Простое отключение анимации и замена взглядов внезапно переносимы, но намного ниже польский, который я создаю для остальной части приложения. Я бы предпочел сделать это:
При вызове функцииAutorotateToInterfaceOrientation: я хотел бы получить непрозрачный снимок зрения, скриншот, если вы захотите, перед просмотром пользователя перед ротацией. Затем, после того, как ротация завершена, и система применила преобразования вида и т.д., Я могу показать снимок, который я сохранил, и анимировать переход по своему выбору к новому представлению. После того, как он будет завершен, я могу освободить свой снимок и перейти дальше.
Есть ли способ сделать это, что не дорого?
Единственный другой вариант, о котором я могу думать, - это вернуть NO во все ориентации, отличные от моего по умолчанию, а затем отреагировать, применив мои собственные анимации и преобразования. Я предпочел бы использовать систему, чтобы сделать это, однако, поскольку я чувствую, что это возможно, это может привести к поведению клавиатуры "undefined" в ручном просмотре и т.д.
Мысли?
Ответы
Ответ 1
Я могу гарантировать вам [window drawRect:] не будет работать. Большинство просмотров не реализуют drawRect: и это, конечно, не рекурсивно, как на mac.
drawInContext: также довольно сильно сидит за спиной, так как он в корне просит слой рисовать сам, а не его подслои рекурсивно. "Реализация по умолчанию ничего не делает". говорит все.
Я реализую это для приложения Cliff Bar Save Our Snow в магазине приложений, выполнив следующие действия:
- Проведите иерархию слоев рекурсивно, получая содержимое из каждого слоя. Если он пахнет изображением, используйте методы CGContext, чтобы привлечь его в свой контекст.
- Во время ходьбы убедитесь, что применяете преобразования/положения каждого слоя, когда вы вызываете рекурсивно
Да, довольно большая боль в заднице. Но да, это работает очень хорошо и прошло через Apple:).
Ответ 2
- (UIImage *)captureView:(UIView *)view {
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[view.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Найдено здесь:
http://discussions.apple.com/thread.jspa?messageID=8358740
Ответ 3
Этот код работал у меня
- (UIImage *)captureScreenInRect:(CGRect)captureFrame {
CALayer *layer;
layer = self.view.layer;
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenImage;
}
Ответ 4
На Mac это так просто... вам просто нужно -bitmapImageRepForCachingDisplayInRect:
, но, конечно, iPhone не имеет такой вещи.
Я думаю, что я бы напал на это, установив графический контекст и набрав [window drawRect:...]
на нем, чтобы захватить текущее изображение экрана. Это немного из спецификации, потому что вы действительно не должны называть -drawRect:
самостоятельно. Я бы немного нервничал из-за побочных эффектов, но это может быть хорошо. Если вы контролируете весь экран, вы можете, конечно, вытащить код рисования из -drawRect:
, чтобы вы не вызывали его напрямую.
Аналогичным подходом было бы использовать CALayer -drawInContext:
текущего -presentationLayer
. Это может быть немного больше "в спецификации", так как законно передавать этот собственный контекст. Но я не знаю, сможете ли вы правильно получить все подзадачи. Возможно, это зависит от характера вашего UIWindow.
В любом случае, большой вопрос. Возможно, у кого-то есть более умное решение, но так я бы напал на него.
EDIT: Спасибо Роб Террелл и его умный UIApplication + TVOut.m, я был представлен
для частного метода UIGetScreenImage(), который возвращает CGImageRef. Если вы готовы пойти на частные методы, это хороший вариант для вас. Учитывая его название и функциональность, он выглядит довольно стабильным для меня и вряд ли нарушит намерения Apple. Я также столкнулся с довольно приятным обсуждением Источник воздуха. Прочитайте комментарии по нескольким ссылкам.