2012-07-14 8 views
5

Mam problemy z setNeedsDisplay. Myślałem, że to powinno wywoływać wywołania drawRect: dla widoku, do którego jest wywoływane, i hierarchii poniżej, jeśli jest w granicach widoku, ale nie znajduję, żeby tak było. Oto moja konfiguracja:setNeedsDisplay nie wyzwala drawRect w subviews zgodnie z oczekiwaniami

Z delegata aplikacji utworzę widok, którego rozmiar to kwadrat obejmujący zasadniczo cały ekran nieruchomości. Ten widok nazywa się TrollCalendarView. Niewiele się dzieje z TrollCalendarView, z wyjątkiem obrotu wywołanego przez kompas.

Istnieje 7 subviews od TrollCalendarView o nazwie PlatformView przeznaczonych do zawierania obiektów 2D do rysowania rozmieszczonych wokół środka TrollCalendarView w układzie 7-stronnym. Więc kiedy iPad jest obrócony, te 7 widoków obraca się tak, że są zawsze zorientowane zgodnie z kierunkami głównymi.

Każdy z subpopulacji PlatformView zawiera 3 subviews o nazwie Tower. Każda wieża zawiera obiekty 2D do rysowania zaimplementowane w drawRect:.

Tak, w skrócie, mam TrollCalendarView z pustym drawRect: i subviews PlatformView and Platformview -> Wieża że każdy ma implementacje drawRect. Dodatkowo Wieża znajduje się w granicach Platformy, a Platforma znajduje się w granicach TrollCalendarView.

W TrollCalendarView dodałem czytnik machnięcia. Po przeprowadzeniu operacji przeciągania właściwość jest aktualizowana, a ja dzwonię pod numer [self setNeedsDisplay], ale nic się nie dzieje. Dodałem wpisy NSLog do metody drawRect: w każdym z tych widoków i wywoływana jest tylko metoda TrollCalendarViewdrawRect:. Jak na ironię, jest to jedyny widok, którego metoda drawRect będzie pusta.

Brak pliku XIB.

Co należy zrobić, aby wywołać metodę drawRect w innych subviewsach? Czy istnieje gdzieś dokumentacja opisująca wszystkie niuanse, które mogą mieć na to wpływ?

Odpowiedz

7

Mam problemy z setNeedsDisplay. Pomyślałem, że powinno wywoływać wywołania funkcji drawRect dla widoku, do którego jest wywoływane, a hierarchii poniżej, jeśli jest w zasięgu widoku.

Nie, to nieprawda. Skąd wziąłeś ten pomysł?

-setNeedsDisplay: dotyczy tylko widoku, do którego jest wysyłany. Jeśli chcesz unieważnić inne widoki, musisz dodać trochę kodu, aby wysłać im także -setNeedsDisplay:. To wszystko.

+0

Mam ten pomysł z odpowiedzi na podobne pytania tutaj na stackoverflow. Po prostu wyszukaj podgląd podrzędny setNeedsDisplay dla próbek. Istnieje kilka. –

+0

Pójdę za tą sugestią, chyba że nauczę się innej drogi. To przynajmniej pasuje do moich odkryć podczas testów. –

+1

Istnieje niestety dużo hałasu na SO i wiele blind-the-blind. Pytania, na które patrzysz, mają bardzo mało głosów, więc prawdopodobnie niewiele osób je widziało lub miało szansę je poprawić. Jeśli dopiero zaczynasz, dokumenty Apple są o wiele bardziej niezawodne. –

5

Myślę, że jest to optymalizacja w ramach; Jeśli twoje subviews nie muszą ponownie narysować, to jest to znacząca poprawa wydajności. Zdaj sobie sprawę, że prawie wszystko, co można animować, nie wymaga rysowania (przesuwanie, skalowanie itp.).

Jeśli wiesz że wszystkie subviews powinny być odnawiany (a nie po prostu przeniesiony), a następnie zastąpić setNeedsDisplay w głównym widoku i zrobić tak:

-(void) setNeedsDisplay { 
    [self.subviews makeObjectsPerformSelector:@selector(setNeedsDisplay)]; 
    [super setNeedsDisplay]; 
} 

Ja testowałem to i to powoduje również przerysowanie wszystkich subviews. Pamiętaj, że zdobędziesz punkty karmy za wydajność, jeśli w jakiś sposób przefiltrujesz swoje subviews i upewnij się, że wysyłasz je tylko do subskrybentów, które rzeczywiście wymagają przerysowania ... a nawet więcej, jeśli potrafisz wymyślić, jak , a nie, aby je przerysować . :-)

+0

Dzięki. Spróbuję tego. W moim scenariuszu, 7 subpoprzedziałów platformy nie musi być przerysowanych. Dokładnie dwie trzecie pozostałych 21 subviews będzie musiało zostać przerysowanych. Wiedza o tym, które z 21 trzeba przerysować, jest efektywnie obliczana w funkcji drawRect i nie można jej wykonać skuteczniej w innym miejscu. Po prostu ciekawy - w jaki sposób ramy zawetują moją decyzję (twój komentarz dotyczący optymalizacji)? Wygląda na to, że w pierwszym rzędzie nie ma to celu, jakim jest setNeedsDisplay. –

+0

Nie. Nie działa. Otrzymuje tylko subviews. Potrzebuję przerysowania podekspozycji tych subviews. Postanowiłem wykonać pracę chodzenia po drzewie w punkcie, w którym muszę ustawić setNeedsDisplay. Dzięki za sugestię. –

Powiązane problemy