2012-05-03 11 views
5

Ho riscontrato un problema di schermo su un CATiledLayer quando l'UIScrollView genitore è ingrandita.CATiledLayer viene rimosso e rinfrescato Durante lo zoom in iPad 3rd gen

sto rendering di una pagina PDF in un CATiledLayer sostenuta UIView. Ha un'altra UIImageView dietro, che contiene un'immagine a bassa risoluzione della pagina disegnata da CATiledLayer. Quando eseguo lo zoom, funziona come previsto. CATiledLayer renderà un'immagine a risoluzione più alta in base al livello di zoom.

Il problema si verifica dopo lo zoom. Se eseguo lo zoom avanti, basta lasciare solo l'iPad, l'immagine visualizzata si sfoca e quindi si riapre. Sembra che il CATiledLayer sia stato rimosso, dal momento che vedo l'immagine sfocata a bassa risoluzione nella vista di supporto, quindi il CATiledLayer viene ridisegnato, cioè vedo l'effetto di piastrellatura e la riaffilatura dell'immagine. Questo succede se lascio l'app da solo e aspetto circa 30-40 secondi. L'ho osservato solo su iPad 3rd gen (New iPad, iPad3, qualunque cosa). Sto anche testando su iPad2 e devo ancora incontrare il problema.

Qualcun altro ha riscontrato questo problema? Qualche causa nota e, possibilmente, soluzioni?

Edit:

I miei metodi UIScrollViewDelegate sono i seguenti:

// currentPage, previousPage, and nextPage are the pdf page views 
// that are having the refresh problem 

- (void)positionBufferedPages { 
    // performs math {code omitted} 

    // then sets the center of the views 
    [previousPage.view setCenter:...];   
    [nextPage.view setCenter:...]; 
} 

- (void)hideBufferedPages { 
    if ([previousPage.view isDescendantOfView:scrollView]) { 
    [previousPage.view removeFromSuperview]; 
    } 

    if ([nextPage.view isDescendantOfView:scrollView]) { 
    [nextPage.view removeFromSuperview]; 
    }   
} 

- (void)showBufferedPages { 
    if (![previousPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:previousPage.view]; 
    } 

    if (![nextPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:nextPage.view]; 
    } 

    if (![currentPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:currentPage.view]; 
    } 
} 

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 
    return currentPage.view; 
} 

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view { 
    [self hideBufferedPages]; 
} 

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollViewParam withView:(UIView *)view atScale:(float)scale { 
    [self positionBufferedPages]; 
    [self showBufferedPages];  
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView { 
    // nothing relating to the pdf page view 
    // but does set the center of some other subviews on top of the pdf page views 
} 

Non sono sicuro di come utile questa sarà, però, come lo ScrollView non riceve in ingresso, mentre il problema si verifica. Come accennato in precedenza, la pagina pdf viene caricata sul CATiledLayer, quindi lascio l'iPad da solo (nessun input viene ricevuto dal dispositivo) e CATiledLayer si ridisegna da solo.

ho provato anche le chiamate da cattura setNeedsDisplay, setNeedsDisplayInRect:, setNeedsLayout, e setNeedsDisplayOnBoundsChange: sia la vista e lo strato di piastrelle, ma il ridisegno accade senza alcuna di quelle funzioni sempre chiamato. drawLayer:inContext: viene chiamato, ovviamente, ma la traccia mostra solo alcune chiamate al quarzo avviate in un thread in background (come previsto, dato che i livelli piastrellati preparano il contenuto in background), quindi non è di aiuto neanche.

Grazie in anticipo!

+0

Potrebbe essere a causa del display retina ad alta risoluzione dell'ipad 3? Stai impostando correttamente il contenuto CATiledLayerScale? Inoltre, nel codice di rendering della creazione PDF personalizzato dovresti utilizzare UIGraphicsBeginImageContextWithOptions e impostare la scala di conseguenza – Lefteris

+0

Non sto utilizzando UIGraphicsBeginImageContextWithOptions, ma utilizzo CGContextScaleCTM per impostare la scala. C'è una differenza? Sembra che sto rendendo il pdf correttamente. Il mio problema è che CATiledLayer in qualche modo ridisegna se stesso senza motivo dopo un po '. – Altealice

+0

È necessario impostare il contenuto CATiledLayerScale sulla scala [[Scala UIScreen mainScreen]] – Lefteris

risposta

1

Come viene visualizzato l'utilizzo della memoria della tua app? CATiledLayer scarterà la sua cache e ridisegnerà se si verifica un avviso di memoria. L'ho visto fare anche senza l'invio di avvertimenti di memoria all'app (solo un carico di memoria più alto del solito). Utilizzare gli strumenti per vedere l'utilizzo della memoria. Potrebbe essere necessario utilizzare lo strumento OpenGL ES Driver per vedere cosa sta succedendo con la memoria grafica.

+0

Sto registrando gli avvertimenti di memoria, ma non si innesca quando si verifica il ridisegno. proverò a controllare con gli strumenti, grazie per le informazioni! – Altealice

+0

Quindi, come hai risolto questo problema? Molti di noi stanno avendo lo stesso problema e una soluzione sarebbe ottima – Brodie

1

Ho avuto lo stesso identico problema. Nel mio caso è stato causato dall'uso della funzione UIGraphicsBeginImageContext(); questa funzione non tiene in considerazione la scala, che dà problemi a un display retina. La soluzione era di sostituire la chiamata con UIGraphicsBeginImageContextWithOptions(), con il parametro scale (= third) impostato su 0.0.

Se il codice si basa sul codice di esempio di visualizzazione PDF di Zooming PDF da Apple, come ho fatto io, è probabile che questo risolva anche il tuo problema.

+0

l'impostazione per ridimensionare a 0.0 è falsa ... dovrebbe essere impostata in questo modo: UIGraphicsBeginImageContextWithOptions (frame.size, NO, [[UIScreen mainScreen] scale]); – Lefteris

+0

Anche il tuo modo funziona ovviamente, ma l'impostazione della scala su 0.0 ha lo stesso effetto. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html – Stuart

+0

Interessante. Grazie. Non sto chiamando UIGraphicsBeginImageContext(), però, dato che sto disegnando usando 'drawlayer: inContext:'. Stai usando un metodo diverso? – Altealice

1

Longshot, c'è qualche possibilità che chiami metodi sulle viste dal thread non principale? Ogni sorta di cose funky inaspettate può accadere se lo fai.

+0

Sì, ci sono cose che accadono in background, ma nessuna loro dovrebbero chiamare il punto di vista.Se questo è il caso, allora la roba di fondo potrebbe consumare memoria e causare ridisegni come dice Josh.Vado a controllare quando torno al lavoro domani – Altealice

1

Ho parlato con un ingegnere Apple di questo e la risposta breve è che iOS ha solo X quantità di memoria disponibile per memorizzare un CATiledLayer nella cache e sul display Retina dell'iPad, ci sono troppi pixel per usare più di uno strato.

Avevo utilizzato due CATileLayer per visualizzare una vista mappa e una vista di disegno in alto. Ho rimosso il secondo CATiledLayer e il problema è andato via.

+0

. Capisco. Buono a sapersi. Grazie per condividere! :) – Altealice

Problemi correlati