2010-09-05 12 views
7

Mam widoku warstwy hosting skonfigurować tak jak to w zwyczaju NSView podklasy:Wywołanie setNeedsDisplay: TAK na warstwie hosting pogląd nie przerysować widok

[self setLayer:rootLayer]; 
[self setWantsLayer:YES]; 

I dodać wszystkie podwarstwy do drzewa warstwy po wywołaniu setNeedsDisplay na każdej podwarstwie. Zawartość każdej warstwy zapewnia metoda delegata mojej warstwy.

Oto mój problem:

Po zainicjowaniu moim zdaniem widok dostaje narysować prawidłowo. Jednak po zmianie modelu i wywołaniu [myCustomView setNeedsDisplay:YES]; z kontrolera widoku, nie jest wywoływana drawLayer:inContext.

Jestem zdezorientowany teraz jak zaktualizować widok:

  • muszę wywołać metodę setNeedsDisplay na każdym CALayer w drzewie warstw?
  • Czy wywołanie setNeedsDisplay:YES na samym widoku hosta warstw nie może spowodować odrysowania drzewa całej warstwy?

Dzięki za pomoc.

Edit

Znalazłem coś w klasie NSView odwoływać

Widok warstwy wspierany jest pogląd, że jest wspierany przez warstwę Core Animation. Wszelkie rysunki wykonane przez widok są buforowane w warstwie podkładu. Skonfigurowałeś widok warstwowy, po prostu wywołując metodę setWantsLayer: z wartością YES. Klasa widoku automatycznie utworzy warstwę pomocniczą dla ciebie i użyjesz mechanizmów rysowania klasy widoku. Podczas korzystania z widoków z warstwami nigdy nie należy bezpośrednio wchodzić w interakcję z warstwą.

Widok hostingu warstw jest widokiem zawierającym warstwę Core Animation, którą użytkownik chce bezpośrednio manipulować. Tworzysz widok hostingu warstw, tworząc instancję klasy warstwy Core Animation i ustawiając ją przy użyciu metody setLayer: view. Po wykonaniu tej czynności należy wywołać metodę setWantsLayer: z wartością YES. Podczas korzystania z widoku hostingu warstw nie należy polegać na widoku do rysowania ani dodawać subviews do widoku hostingu warstw.

link to documentation

W moim przypadku mam widok warstwy-gospodarzem. Czy to rzeczywiście oznacza, że ​​muszę ręcznie uruchomić odświeżanie? Czy powinienem wdrożyć metodę pseudo drawRect w niestandardowym programie NSView, aby wywołać odpowiedni setNeedsDisplay na zmienionych CALayers?

Odpowiedz

9

Po dalszych badaniach w Apple's sample code menu w stylu kiosku dowiedziałem się, że jeśli korzystasz z widoku hostingu warstw, musisz zadbać o aktualizacje ekranu, które są konieczne z powodu zmian w modelu. Wywołanie setNeedsDisplay:YES na NSView nic nie da.

Co należy zrobić, jeśli trzeba zaktualizować widok, należy napisać metodę taką jak reloadData, a następnie należy wywołać setNeedsDisplay na każdej CALayerze, która potrzebuje odświeżenia. Nadal nie jestem pewien, czy wywołanie tej metody na poziomie warstwy głównej będzie propagować przez wszystkie warstwy podrzędne, ale nie sądzę.

Rozwiązałem problem, dzwoniąc pod numer setNeedsDisplay na poszczególnych CALayerach, które wymagały recyklingu. Działa bez problemów.

+0

Twój link do przykładowego kodu jest uszkodzony, być może jest to zamiennik: https://developer.apple.com/library/mac/samplecode/CoreAnimationKioskStyleMenu/Introduction/Intro.html#//apple_ref/doc/uid/ DTS40009512 –

2

Jest również często stosowane praktyki mające pusty „drawRect” a la -(void) drawRect:(NSRect)dirtyRect {} pomóc zmusić rzeczy do rysowania, wierzę poprzez dobry ole view.needsDisplay = YES;.

i należy zauważyć, że .. co rzeczywiście dzieje, że - mówiąc swoje NSView *view; jest layer.delegate = view; powoduje, że warstwa być sporządzone przy [layer setNeedsDisplay]; nazywa .... poprzez - (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {...} ..

wzdłuż samo żyła ... kiedy mówiąc layer.layoutManager = view ... kolejne wymagania, które [layer setNeedsLayout]; będą spełnione tylko wtedy, gdy jest realizowany metodą - (void) layoutSublayersOfLayer:(CALayer *)layer {..} ..

tych ważnych pojęć są pomijane/porozrzucane w docs Apple ... i są one naprawdę tak kluczowy dla absolutnie jakiegokolwiek działania.

+0

możesz wyjaśnić nieco bardziej przyjazny dla początkujących sposób. – carbonr

+0

@carbonr Wiem, że to jest mylące. Ale to, co powiedziałem, jest tak proste, jak to tylko możliwe. Jeśli rzeczy nie wyświetlają się poprawnie, a widok jest delegatem warstwy, musisz zaimplementować 'drawLayer: inContext' i może mieć puste' drawRect: 'AND wywołanie' setNeedsDisplay'. Przeczytaj to 10 razy, jeśli musisz, ale wszystkie informacje są dostępne. Jeśli dobrze pamiętam, to jest. ;) –

Powiązane problemy