2009-10-11 8 views
10

So habe ich eine benutzerdefinierte UIView-Unterklasse, die das Zeichnen von abgerundeten Kanten ermöglicht. Die Sache zeichnet sich perfekt ab, jedoch füllt der Hintergrund immer die ganzen Grenzen aus, obwohl er zuerst auf einen Pfad abgeschnitten hat. Der Rahmen zeichnet auch über den rechteckigen Hintergrund, trotz der Tatsache, dass ich die Grenze in drawRect zeichnen: vor dem Hintergrund. Also habe ich den gesamten Inhalt von drawRect: entfernt, der jetzt praktisch leer ist - trotzdem wird der Hintergrund gezeichnet!UIView Unterklasse zeichnet Hintergrund trotz komplett leer drawRect: - warum?

Jeder eine Erklärung dafür? Ich setze die backgroundColor im Interface Builder. Vielen Dank!

+0

Es ist wahrscheinlich ein Problem mit Ihrem Zeichencode. Können Sie es posten, damit wir es uns ansehen können? Meine Vermutung ist, dass du irgendwo zeichnest, dass du entweder Alpha-Werte ignorierst oder etwas undurchsichtiges über das zeichnest, was du gedacht hast. Nur um sicher zu gehen, dass Sie die Hintergrundfarbe eingestellt haben, haben Sie das Alpha richtig gesetzt? –

+0

Nun, ich kann meine drawRect :, aber wie gesagt, es ist komplett leer:

 - (void) drawRect:(CGRect)rect { } 
Das Alpha ist in IB gesetzt, und es wird in welcher Farbe ich es gesetzt, mit was auch immer Alpha. Ich gehe davon aus, dass dort etwas interior sein muss, aber es gibt keine neue Superview und keine Subview, die den Hintergrund zeichnen könnte. Auch die Hintergrundfarbe der Ebene der Ansicht ist null. – Pascal

Antwort

20

Entschuldigung für diesen Monolog. :)

Die Sache ist, dass die UIView-Ebene scheinbar den Hintergrund zeichnet, der unabhängig von drawRect: ist. Aus diesem Grund können Sie den Hintergrund nicht entfernen, indem Sie drawRect: überschreiben.

Sie können entweder - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx außer Kraft setzen und die Schicht Unentschieden machen, was Sie wollen, oder Sie - (void) setBackgroundColor:(UIColor *)newColor außer Kraft setzen und nicht NewColor-background, aber zu Ihrer eigenen Ivar, wie myBackgroundColor ordnen. Sie können dann myBackgroundColor in drawRect verwenden; um den Hintergrund zu zeichnen, wie Sie möchten.


Aufschalten setBackgroundColor:

eine Instanzvariable Definieren Sie Ihre Hintergrundfarbe zu halten, z.B. myBackgroundColor. In Ihrem init Methoden, stellen Sie die reale Hintergrundfarbe der Clear zu sein:

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

Aufschalten:

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

Dann myBackgroundColor in Ihrem drawRect verwenden: Methode. Auf diese Weise können Sie die von Interface Builder (oder Xcode4) in Ihrem Code zugewiesene Farbe verwenden.

0

Dies ist leicht reproduzierbar:

Erstellen Sie eine neue View-Based iPhone-Anwendung. Erstellen Sie eine UIView-Unterklasse, und lassen Sie die drawRect: -Methode vollständig leer. Ziehen Sie in Interface Builder eine UIView in die Hauptansicht, weisen Sie ihr eine Hintergrundfarbe zu und legen Sie die Klasse der Ansicht für Ihre Unterklasse fest. Speichern, erstellen und ausführen, und sehen, die Ansicht zeigt die Hintergrundfarbe.

Ich habe dieses Verhalten umgehen durch Überschreiben von SetBackgroundColor: und die Farbe zu meinem eigenen Ivar zuweisen, immer die BackgroundColor-Eigenschaft Nil verlassen. Das funktioniert, aber ich frage mich immer noch, warum das so funktioniert.

6

Ich zögere, dies zu empfehlen, weil ich dich nicht beleidigen will, aber hast du opak für NO gesetzt?

+1

Nichts für ungut, die Frage ist eigentlich eine gute: Ja, opak wurde auf NEIN eingestellt. :) – Pascal

+0

Manchmal ist es so einfach ... Danke! –

8

Hier ist ein einfacher fix:

self.backgroundColor = [UIColor clearColor]; 
+0

Ja, das wird durch das Überschreiben von setBackgroundColor: erreicht. Ich fragte mich mehr, warum überhaupt etwas gezeichnet wurde, trotz drawRect: leer sein. Die Antwort war, dass der Hintergrund in drawLayer: inContext: gezeichnet wird. – Pascal

0

Sie

clearsContextBeforeDrawing = NO 

so einfach Es ist festgelegt sollte.

Vom UIView Reference Docs

Oops. Ich habe die Frage missverstanden. Das OP (Original-Poster) möchte, dass sein benutzerdefiniertes Steuerelement die Standard-Eigenschaft "backgroundColor" unterstützt (z. B. vom GUI-Designer festgelegt), aber das System diese Farbe nicht zeichnen soll. Der OP möchte den bg selbst malen, damit er die Ecken abrunden kann.

In diesem Fall ist der Post zum Überschreiben der Ebenenzeichnung korrekt.

Die von mir gepostete Lösung verhindert, dass das UI-System den Puffer vor dem Zeichnen löscht. Wenn Sie kein bg definiert haben, löscht das iOS den Puffer Ihrer Ansicht und setzt alle Pixel auf transparentes Schwarz, wenn clearsContextBeforeDrawing gesetzt ist. Für eine Vollbildansicht dauert das etwa 5 ms in einem iPad3, also ist es nicht kostenlos (das Schieben von 2048x1536 Pixeln ist nie frei). Zum Vergleich wird eine Vollbild-Bitmap (mit kCGBlendModeCopy zum Erzwingen von Blitting) ~ 25 ms benötigt (mit Quarz, nicht mit GPU).

+0

Dies verhindert nicht, dass backgroundColor gezeichnet wird. zumindest nicht in meinem Schnelltest. – Pascal

+0

Was passiert, wenn Sie backgroundColor deaktivieren? –

+0

Dann funktioniert es, und deshalb habe ich 'setBackgroundColor:' außer Kraft gesetzt, um keine Farbe auf super einzustellen und die Hintergrundfarbe in meinem eigenen ivar zu speichern. Auf diese Weise wird die Hintergrundfarbe, die im Interface Builder zugewiesen wurde, in meinem benutzerdefinierten 'drawRect:' verwendet und muss nicht im Code behandelt werden. :) – Pascal

Verwandte Themen