2012-02-03 7 views
5

Ho una vista mappa personalizzata che è composta da un UIScrollView. La sottoview della vista di scorrimento è supportata da un CATiledLayer. Tutto funziona alla grande qui. Panning & lo zoom carica nuove tessere mappa e tutto funziona bene.scattare un'istantanea di immagini della vista con supporto CATiledLayer in UIScrollView

Quello che voglio fare è catturare fotogrammi di video di animazioni a questa vista di scorrimento. In sostanza, voglio creare un video di modifiche animate a contentOffset e zoomScale della vista di scorrimento.

So che il concetto è valido in quanto è possibile ottenere la funzione API privata UIGetScreenImage() per acquisire lo schermo dell'app, ad esempio 10 fps, combinare queste immagini e ottenere animazioni di riproduzione che sono fluide e con le curve di temporizzazione utilizzate da le animazioni della vista a scorrimento.

Il mio problema, ovviamente, è che non posso usare l'API privata. Passare attraverso le alternative delineate da Apple here mi lascia praticamente un'opzione valida: chiedere un CALayer a renderInContext e prendere uno UIGraphicsGetImageFromCurrentImageContext() da quello.

Questo non sembra funzionare con viste CATiledLayer -backed, però. Un'immagine bloccata e non ingrandita è ciò che viene catturato, come se le tessere a risoluzione più alta non venissero mai caricate. Questo ha un po 'senso dato che CATiledLayer disegna in background thread per le prestazioni e chiamando renderInContext dal thread principale potrebbe non catturare questi aggiornamenti. Il risultato è simile anche se eseguo il rendering dello strato piastrellato presentationLayer.

Esiste un modo sanzionato da Apple di acquisire un'immagine di una vista CATiledLayerbackback durante il corso delle animazioni della vista di scorrimento contenente? O in qualsiasi momento, del resto?

+0

Qualcuno ha postato la risposta qui: http://stackoverflow.com/questions/5526545/render-large-catiledlayer-into-smaller- area –

risposta

1

BTW, questo è possibile se si implementa correttamente renderLayer:inContext: nella vista CATiledLayerbackback.

0

Ho eseguito un test rapido e utilizzando renderInContext: su una vista che si adattava alla visualizzazione a scorrimento sembrava funzionare. Hai provato?

+0

Sì. Ho inserito alcuni esempi di codice che dimostrano questo problema in modo più sintetico: https://github.com/incanus/TiledLayerSnapTest Si noti che l'acquisizione di un normale 'UIView' funziona bene, ma la vista' CATiledLayer'-backed appare vuota grigio. – incanus

0

Questo codice funziona per me.

- (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; 

}

codice di esempio completa trovato qui: https://github.com/gortega56/CCCanvasView

Problemi correlati