2012-05-03 30 views
5

mam wystąpił problem odświeżania na CATiledLayer kiedy UIScrollView rodzic jest powiększony.CATiledLayer usuwane i odświeżony natomiast powiększony iPada 3. gen

Mam renderowania strony PDF w CATiledLayer kopii UIView. Ma za sobą inny UIImageView, który zawiera obraz o niskiej rozdzielczości strony, którą rysuje CATiledLayer. Kiedy przybliżam, działa zgodnie z oczekiwaniami. CATiledLayer wyświetli obraz o wyższej rozdzielczości w zależności od poziomu powiększenia.

Problem występuje po powiększeniu. Jeśli powiększę, a następnie zostaw iPada sam, wyświetlany obraz rozmazuje się, a następnie ponownie wyostrza. Wygląda na to, że CATiledLayer jest usuwany, ponieważ widzę rozmazany obraz w niskiej rozdzielczości w widoku podkładu, a następnie CATiledLayer zostaje przerysowany, tj. Widzę efekt kafelkowania i ponowne wyostrzenie obrazu. Dzieje się tak, gdy zostawiam samą aplikację i poczekam około 30 do 40 sekund. Obserwowałem to tylko na iPadzie 3. generacji (nowy iPad, iPad3, cokolwiek). Testuję również na iPad2 i jeszcze nie spotkałem się z tym problemem.

Czy ktoś jeszcze napotkał ten problem? Każda znana przyczyna i, być może, rozwiązania?

Edit:

Moje metody UIScrollViewDelegate są następujące:

// 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 
} 

Nie wiem, jak to będzie pomocne, choć, jak Scrollview nie odbiera wejście podczas gdy problem się nie dzieje. Jak wspomniano powyżej, strona pdf jest ładowana do CATiledLayer, następnie pozostawiam iPada sam (urządzenie nie otrzymuje żadnych danych wejściowych), a CATiledLayer sam przerysuje.

Próbowałem również połączenia przyciąć do setNeedsDisplay, setNeedsDisplayInRect:, setNeedsLayout i setNeedsDisplayOnBoundsChange: zarówno na widoku a warstwą płytkami, ale odrysowywanie dzieje się bez żadnej z tych funkcji o nazwie uzyskiwanie. drawLayer:inContext: jest wywoływana, oczywiście, ale ślad pokazuje tylko niektóre wywołania kwarcowe uruchamiane w wątku tła (zgodnie z oczekiwaniami, ponieważ warstwy kafelkowe przygotowują treść w tle), więc to też nie pomaga.

Z góry dzięki!

+0

Czy to możliwe z powodu ekranu Retina o wysokiej rozdzielczości w iPadzie 3? Czy poprawnie ustawiasz zawartośćScale na CATiledLayer? Również w twoim niestandardowym kodzie renderującym tworzenie PDF powinieneś używać UIGraphicsBeginImageContextWithOptions i odpowiednio ustawić skalę. – Lefteris

+0

Nie używam UIGraphicsBeginImageContextWithOptions, ale używam CGContextScaleCTM do ustawienia skali. Czy istnieje różnica? Wygląda na to, że poprawnie renderuję plik pdf. Mój problem polega na tym, że CATiledLayer po jakimś czasie przerysowuje się bez żadnego powodu. – Altealice

+0

Powinieneś ustawić zawartość treści CATiledLayerScale na skalę [[Główne ekrany UIScreen]] – Lefteris

Odpowiedz

1

Jak wygląda wykorzystanie pamięci przez aplikację? CATiledLayer odrzuci pamięć podręczną i przerysuje, jeśli pojawi się ostrzeżenie o pamięci. Widziałem, jak to robi, nawet bez ostrzeżeń o pamięci wysyłanych do aplikacji (tylko większe niż zwykle obciążenie pamięci). Użyj narzędzi, aby zobaczyć użycie pamięci. Może zajść potrzeba użycia instrumentu OpenGL ES Driver, aby zobaczyć, co dzieje się z pamięcią graficzną.

+0

Zajmuję się rejestrowaniem ostrzeżeń o pamięci, ale nie jest on wyzwalany, gdy nastąpi odrysowanie. Próbuję sprawdzić przy pomocy przyrządów .. Dzięki za informację! – Altealice

+0

Jak rozwiązałeś ten problem? Wielu z nas ma ten sam problem i rozwiązanie byłoby wspaniałe – Brodie

1

Miałem dokładnie ten sam problem. W moim przypadku było to spowodowane użyciem funkcji UIGraphicsBeginImageContext(); ta funkcja nie uwzględnia skali, co powoduje problemy na wyświetlaczu siatkówki. Rozwiązaniem było zastąpienie wywołania UIGraphicsBeginImageContextWithOptions(), przy ustawieniu parametru scale (= third) na 0,0.

Jeśli oparłeś swój kod na kodzie przykładowym Zooming PDF Viewer firmy Apple, tak jak ja, to jest szansa, że ​​rozwiąże to twój problem.

+0

ustawienie skali na 0.0 jest fałszywe ... powinno być ustawione w następujący sposób: UIGraphicsBeginImageContextWithOptions (frame.size, NO, [[UIScreen mainScreen] scale]); – Lefteris

+0

Twój sposób działa również oczywiście, ale ustawienie skali na 0.0 daje ten sam efekt. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html – Stuart

+0

Interesujące. Dzięki. Nie nazywam jednak UIGraphicsBeginImageContext(), ponieważ rysuję za pomocą 'drawlayer: inContext:'. Czy używasz innej metody? – Altealice

1

Longshot, czy przypadkiem nie wywołasz żadnych metod na widokach z innego niż główny wątku? Wszelkiego rodzaju niespodziewane, ostre rzeczy mogą się zdarzyć, jeśli tak zrobisz.

+0

Tak, w tle dzieje się coś, ale żaden z powinny one wywoływać widok, jeśli tak jest, to tło może pochłaniać pamięć i powodować przerysowanie, jak mówi Josh.) Sprawdzę, kiedy wrócę do pracy jutro – Altealice

1

Rozmawiałem z inżynierem Apple o tym i krótka odpowiedź jest taka, że ​​iOS ma tylko X ilość pamięci dostępnej do buforowania CATiledLayer i na wyświetlaczu Retina iPada, jest po prostu zbyt wiele pikseli, aby użyć więcej niż jeden warstwa.

Wykorzystałem dwie warstwy CATileLayers do wyświetlenia widoku mapy i widoku rysunku na wierzchu. Usunąłem drugą kategorię CATiledLayer i problem zniknął.

+0

Rozumiem, dobrze wiedzieć. do dzielenia się! :) – Altealice

Powiązane problemy