2009-10-11 9 views
10

Mam więc niestandardową podklasę UIView, która umożliwia rysowanie zaokrąglonych krawędzi. Rzecz rysuje się idealnie, jednak tło zawsze wypełnia całe granice, pomimo przycięcia do ścieżki w pierwszej kolejności. Granica także rysuje powyżej prostokątnego tła, pomimo faktu, że rysuję granicę w drawRect: przed tłem. Usunąłem więc całą zawartość drawRect :, która jest teraz praktycznie pusta - niemniej jednak tło zostanie narysowane!Podklasa UIView rysuje tło pomimo całkowicie pustego drawRect: - dlaczego?

Czy ktoś to wytłumaczy? Ustawiłem backgroundColor w Interface Builder. Dzięki!

+0

To prawdopodobnie problem z kodem rysunku. Czy możesz to opublikować, abyśmy mogli rzucić okiem? Domyślam się, że gdzieś rysujesz w sposób, który albo ignoruje wartości alfa, albo rysuje coś nieprzezroczystego nad tym, co myślałeś, że wyciągnąłeś. Ponadto, aby upewnić się, że po ustawieniu 'backgroundColor' masz odpowiednio ustawiony zestaw alpha? –

+0

Cóż, mogę opublikować mój drawRect :, ale jak już powiedziałem, jest on całkowicie pusty:

 - (void) drawRect:(CGRect)rect { } 
Alfa jest ustawione w IB, a rysuje się na dowolny kolor, który ustawię, z czymkolwiek alfa. Zakładam, że coś musi się dziać wewnątrz, ale nie ma nowego superviewu i żadnego wydziału, który mógłby rysować tło. Również backgroundColor warstwy widoku jest zerowy. – Pascal

Odpowiedz

20

Przepraszamy za ten monolog. :)

Chodzi o to, że warstwa UIView najwyraźniej rysuje tło, które jest niezależne od drawRect:. Dlatego nie można pozbyć się tła, przesłonić drawRect:.

Można też zastąpić - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx i zrobić losowanie warstwy co chcesz, lub zastąpić - (void) setBackgroundColor:(UIColor *)newColor i nie przypisywać newColor do backgroundColor, ale na swój ivar, jak myBackgroundColor. Możesz następnie użyć myBackgroundColor w drawRect; narysować tło, jak ci się podoba.


Zastępowanie setBackgroundColor:

Definiowanie instancji zmiennej do przechowywania kolor tła, na przykład myBackgroundColor. W twoich metod init ustawić prawdziwy kolor tła za clearColor:

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    if ((self = [super init...])) { 
     [super setBackgroundColor:[UIColor clearColor]]; 
    } 
    return self; 
} 

Override:

- (void) setBackgroundColor:(UIColor *)newColor 
{ 
    if (newColor != myBackgroundColor) { 
     [myBackgroundColor release]; 
     myBackgroundColor = [newColor retain]; 
    } 
} 

Następnie użyj myBackgroundColor w Twojej drawRect: metoda. W ten sposób możesz użyć koloru przypisanego przez Interface Builder (lub Xcode4) w swoim kodzie.

0

To jest łatwo powtarzalne:

Utwórz nową aplikację opartą na widoku. Utwórz podklasę UIView i pozostaw metodę drawRect: całkowicie pustą. W Konstruktorze interfejsów przeciągnij UIView do głównego widoku, przypisz mu kolor tła i ustaw klasę widoku na swoją podklasę. Zapisz, skompiluj i uruchom, a zobaczysz, widok pokazuje kolor tła.

Ominąłem to zachowanie, przesłoniwszy wartość setBackgroundColor: i przypisując kolor do własnego ivar, zawsze pozostawiając właściwość backgroundColor zerową. To działa, ale wciąż zastanawiam się, dlaczego to działa w ten sposób.

6

Waham się zasugerować to, ponieważ nie chcę Cię urazić, ale czy ustawiłeś opcję NIE?

+1

Bez urazy podjęte, pytanie jest rzeczywiście dobre: ​​Tak, nieprzezroczyste zostało ustawione na NIE. :) – Pascal

+0

Czasami to takie proste ... Dzięki! –

8

Oto łatwiej fix:

self.backgroundColor = [UIColor clearColor]; 
+0

Tak, właśnie to osiągnięto przez przesłonięcie setBackgroundColor :. Bardziej się zastanawiałem, dlaczego w ogóle coś się narysowało, pomimo remisu: być pustym. Odpowiedź była taka, że ​​tło jest rysowane w drawLayer: inContext :. – Pascal

0

Należy ustawić

clearsContextBeforeDrawing = NO 

To takie proste.

Z UIView Reference Docs

Ups. Źle zrozumiałem pytanie. OP (oryginalny plakat) chce, aby ich niestandardowa kontrola obsługiwała standardową właściwość "backgroundColor" (np. Ustawiana przez projektanta GUI), ale NIE chce, aby system malował ten kolor. OP chce sam malować bg, aby mógł zaokrąglić rogi.

W takim przypadku wiadomość o nadpisaniu rysunku poziomu warstw jest poprawna.

Opublikowane przeze mnie rozwiązanie uniemożliwi systemowi UI wyczyszczenie bufora przed rysowaniem. Jeśli nie zdefiniowano bG, jeśli ustawiono clearsContextBeforeDrawing, system iOS wyczyści bufor widoku, ustawiając wszystkie piksele na przezroczyste czarne. Wykonanie tego dla widoku pełnoekranowego zajmuje około 5 ms na iPadzie3, więc nie jest wolne (przesuwając, że 2048 x 1536 pikseli nigdy nie jest). Dla porównania rysowanie pełnoekranowej bitmapy (przy użyciu kCGBlendModeCopy w celu wymuszenia blaknięcia) trwa ~ 25 ms (przy użyciu kwarcu, a nie GPU).

+0

Nie zapobiega to rysowaniu tła backgroundColor; przynajmniej nie jestem moim szybkim testem. – Pascal

+0

Co stanie się, jeśli anulujesz ustawienie backgroundColor? –

+0

Następnie działa, dlatego zdecydowałem się przesłonić 'setBackgroundColor:', aby ustawić kolor na super i zapisać kolor tła do mojego własnego ivar. W ten sposób kolor tła przypisany w konstruktorze interfejsów zostanie użyty w moim niestandardowym 'drawRect:' i nie będę musiał obsługiwać tego w kodzie. :) – Pascal

Powiązane problemy