Jak skutecznie narysować CGPath
na CATiledLayer
? Obecnie sprawdzam, czy obwiednia kafelka przecina obwiednię ścieżki w następujący sposób:
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context {
CGRect boundingBox = CGPathGetPathBoundingBox(drawPath);
CGRect rect = CGContextGetClipBoundingBox(context);
if( !CGRectIntersectsRect(boundingBox, rect) )
return;
// Draw path...
}
Nie jest to zbyt wydajne, ponieważ drawLayer:inContext:
jest wywoływane wielokrotnie z wielu wątków i powoduje wielokrotne rysowanie ścieżki.
Czy jest lepszy, bardziej wydajny sposób na to zrobić?
2 odpowiedzi
Najprostszą opcją jest narysowanie krzywej na duży obraz, a następnie ułożenie go obok siebie. Ale jeśli układasz kafelki, prawdopodobnie oznacza to, że obraz byłby zbyt duży lub po prostu narysowałeś ścieżkę, prawda?
Więc prawdopodobnie musisz podzielić swoją ścieżkę. Najprostszym podejściem jest podzielenie go element po elemencie za pomocą CGPathApply
. Dla każdego elementu możesz sprawdzić jego pole ograniczające i określić, czy ten element mieści się w twoich granicach. Jeśli nie, po prostu śledź ostatni punkt końcowy. Jeśli tak, przejdź do ostatniego widzianego punktu końcowego i dodaj element do nowej ścieżki dla tego kafelka. Kiedy skończysz, każda płytka narysuje własną ścieżkę.
Technicznie rzecz biorąc, „rysujesz” tutaj rzeczy, które wykraczają poza twoje granice (takie jak linia, która rozciąga się poza kafelek), ale jest to znacznie tańsze niż się wydaje. Core Graphics bardzo łatwo przycina pojedyncze elementy. Celem jest uniknięcie obliczania elementów, których w ogóle nie ma w polu ograniczającym.
Pamiętaj, aby buforować wynikową ścieżkę. Nie musisz obliczać ścieżki dla każdej płytki; tylko te, które rysujesz. Ale unikaj przeliczania go za każdym razem, gdy kafelek jest dobierany. Za każdym razem, gdy dane ulegną zmianie, zrzuć pamięć podręczną. Jeśli istnieje bardzo duża liczba płytek, możesz również użyć NSCache
, aby zoptymalizować to jeszcze lepiej.
Nie pokazujesz, gdzie powstaje ścieżka. Jeśli to możliwe, możesz spróbować zbudować ścieżkę w metodzie -drawLayer:inContext:
, tworząc tylko jej część potrzebną do rysowania kafelka.
Podobnie jak w przypadku wszystkich problemów z wydajnością, powinieneś użyć Instruments, aby sprofilować swój kod i dowiedzieć się, gdzie dokładnie znajdują się wąskie gardła. Czy już tego próbowałeś, a jeśli tak, to co znalazłeś?
Na marginesie, czy istnieje powód, dla którego używasz CGPath zamiast UIBezierPath? Z Dokumentacja Apple:
Do tworzenia ścieżek w systemie iOS zaleca się używanie UIBezierPath zamiast funkcji CGPath, chyba że potrzebujesz niektórych funkcji, które zapewnia tylko Core Graphics, takich jak dodawanie wielokropków do ścieżek. Aby uzyskać więcej informacji na temat tworzenia i renderowania ścieżek w UIKit, zobacz „Rysowanie kształtów przy użyciu ścieżek Beziera”.
Podobne pytania
Nowe pytania
iphone
NIE używaj tego znacznika, chyba że adresujesz konkretnie iPhone'a i / lub iPoda touch firmy Apple. W przypadku pytań niezależnych od sprzętu użyj tagu [ios]. Więcej tagów do rozważenia to [xcode] (ale tylko jeśli pytanie dotyczy samego IDE), [swift], [objective-c] lub [cocoa-touch] (ale nie [cocoa]). Proszę powstrzymać się od pytań dotyczących iTunes App Store lub iTunes Connect. Jeśli używasz języka C #, oznacz tagiem [mono].