2012-02-03 12 views
5

Mam niestandardowy widok mapy, który składa się z UIScrollView. Podgląd widoku przewijania jest wspierany przez CATiledLayer. Wszystko działa tutaj świetnie. Przesuwanie powiększenia ładuje nowe kafelki mapy i wszystko działa dobrze.Robienie migawek obrazu widoku CATiledLayer w widoku UIScrollView

Co chcę zrobić, to przechwytywać klatki wideo animacji do tego widoku przewijania. Zasadniczo chcę utworzyć wideo animowanych zmian w widoku przewijania contentOffset i zoomScale.

Wiem, że koncepcja jest dobra, ponieważ mogę uzyskać funkcję prywatnego interfejsu API UIGetScreenImage(), aby uchwycić ekran aplikacji przy powiedzmy 10 klatek na sekundę, połączyć te obrazy i uzyskać animacje odtwarzania, które są płynne i mają krzywe taktowania używane przez animacje widoku przewijania.

Mój problem polega na tym, że nie mogę korzystać z prywatnego API. Przejście przez alternatywy opisane przez Apple here pozostawia mi prawie jedną rzekomo ważną opcję: prosząc o CALayer do renderInContext i biorąc UIGraphicsGetImageFromCurrentImageContext() z tego.

To jednak nie działa z widokami w widoku wstecznym. Zablokowany, nieukierunkowany obraz jest przechwytywany, tak jakby płytki o wyższej rozdzielczości nigdy się nie ładowały. To trochę ma sens, biorąc pod uwagę, że CATiledLayer rysuje w wątkach tła dla wydajności i wywoływanie renderInContext z głównego wątku może nie przechwycić tych aktualizacji. Wynik jest podobny, nawet jeśli renderuję warstwę kafli presentationLayer.

Czy jest obsługiwany przez Apple sposób przechwytywania obrazu z widoku animacji zawierającego program przewijania? A może w którymkolwiek momencie?

+0

Ktoś pisał odpowiedź tutaj: http://stackoverflow.com/questions/5526545/render-large-catiledlayer-into-smaller- obszar –

Odpowiedz

1

BTW, jest to wykonalne, jeśli prawidłowo wdrożysz renderLayer:inContext: w swoim tylnym widoku z .

0

Zrobiłem szybki test i użycie renderInContext: na widoku zawijającym widok przewijania wydawał się działać. Czy próbowałeś tego?

+0

Tak. Podałem przykładowy kod, który przedstawia ten problem bardziej zwięźle: https://github.com/incanus/TiledLayerSnapTest Zauważ, że przechwytywanie zwykłego 'UIView' działa dobrze, ale widok' CATiledLayer' jest pusty szary. – incanus

0

Ten kod działa dla mnie.

- (UIImage *)snapshotImageWithView:(CCTiledImageScrollView *)view 
{ 
// Try our best to approximate the best tile set zoom scale to use 
CGFloat tileScale; 
if (view.zoomScale >= 0.5) { 
    tileScale = 2.0; 
} 
else if (view.zoomScale >= 0.25) { 
    tileScale = 1.0; 
} 
else { 
    tileScale = 0.5; 
} 

// Calculate the context translation based on how far zoomed in or out. 
CGFloat translationX = -view.contentOffset.x; 
CGFloat translationY = -view.contentOffset.y; 
if (view.contentSize.width < CGRectGetWidth(view.bounds)) { 
    CGFloat deltaX = (CGRectGetWidth(view.bounds) - view.contentSize.width)/2.0; 
    translationX += deltaX; 
} 
if (view.contentSize.height < CGRectGetHeight(view.bounds)) { 
    CGFloat deltaY = (CGRectGetHeight(view.bounds) - view.contentSize.height)/2.0; 
    translationY += deltaY; 
} 

// Pass the tileScale to the context because that will be the scale used in drawRect by your CATiledLayer backed UIView 
UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(view.bounds)/view.zoomScale, CGRectGetHeight(view.bounds)/view.zoomScale), NO, tileScale); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextTranslateCTM(context, translationX/view.zoomScale, translationY/view.zoomScale); 

// The zoomView is a subview of UIScrollView. The CATiledLayer backed UIView is a subview of the zoomView. 
[view.zoomView.layer renderInContext:context]; 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

return image; 

}

Pełna przykładowy kod tutaj: https://github.com/gortega56/CCCanvasView

Powiązane problemy