2012-12-06 4 views
7

Ich versuche, die drawRect: Methode von UIView in meiner benutzerdefinierten Ansicht zu überschreiben. Doch meiner Meinung nach definiert eine Grenzradius hat als:UIView überschreiben drawRect bewirkt, dass view nicht gehorcht masksToBounds

sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0]; 
    [self addSubview:sub]; 
    [sub setUserInteractionEnabled:YES]; 
    [self setUserInteractionEnabled:YES]; 
    CALayer *layer = sub.layer; 
    layer.masksToBounds = YES; 
    layer.borderWidth = 5.0; 
    layer.borderColor = [UIColor whiteColor].CGColor; 
    layer.cornerRadius = 30.0; 

Dies funktioniert perfekt und stellt eine schöne Grenze mit einem Grenzradius um meine Ansicht (nicht die diagonal/gerade weiße Linien auf der Rückseite dagegen, sie haben nichts mit dieser Ansicht zu tun):

correct one

Allerdings, wenn ich versuche, die drawRect: Methode meiner Ansicht nach außer Kraft zu setzen, kann ich ein schwarzer Hintergrund nicht zu Grenzen Maskierung sehen. Ich mache keine etwas (derzeit), hier ist mein Code:

-(void)drawRect:(CGRect)rect{ 
    [super drawRect:rect]; 
} 

Und hier ist das Ergebnis:

incorrect one

ich nichts anderes als die Zeichenmethode geändert haben. Wie kann ich die Zeichenmethode überschreiben, während meine Ansicht der Eckenradiusmaske gehorcht? Ist das ein Fehler in iOS oder fehlt mir etwas?

Antwort

3

Ich weiß nicht die vollständige Antwort, aber ich weiß, dass UIViews Implementierung von drawLayer:inContext: anders funktioniert, je nachdem, ob Sie drawRect: implementiert haben oder nicht. Vielleicht ist das Maskieren/Clippen in Grenzen etwas, das es anders macht.

können Sie versuchen, Ihr Problem eine Reihe von Möglichkeiten zu lösen:

  • Ihren Hintergrund transparent machen:

    layer.backgroundColor = [UIColor clearColor].CGColor; 
    
  • sich Clip in Ihrem benutzerdefinierten drawRect::

    - (void)drawRect:(CGRect)rect { 
        [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:30.0] addClip]; 
        [image drawInRect:rect]; // or whatever 
    } 
    
  • schneide die Ecken explizit aus:

    CGContextBeginPath(c); 
    CGContextAddArc(c, r, r, r, M_PI, 3*M_PI_2, 0); 
    CGContextAddLineToPoint(c, 0, 0); 
    CGContextClosePath(c); 
    CGContextClip(c); 
    [[UIColor grayColor] setFill]; 
    UIRectFill(rect); 
    

stahl ich die letzten 2 Anregungen aus dieser großen Präsentation von WWDC 2010: Advanced Performance Optimization on iPhone OS (Video bei this index page aufgeführt - nervend, keine direkte Verbindung).

1

Wahrscheinlich sollten Sie nicht die

[super drawRect:rect] 

in Ihrem drawRect nennen. Apple says dass:

Wenn Sie UIView Unterklasse direkt, Ihre Implementierung dieser Methode nicht super anrufen muss. Wenn Sie jedoch eine andere Sichtklasse unterklassifizieren, sollten Sie Super an einem bestimmten Punkt in Ihrer Implementierung aufrufen.

Es scheint, dass das Aufrufen der Super-Methode seltsames Verhalten verursacht.

2

Dies ist eine alte Frage, aber ich habe kürzlich einen nützlichen Blogeintrag mit dem Titel Abusing UIView gelesen. Darin rät der Autor davon ab, drawRect außer Kraft zu setzen, Dinge wie einen Rahmen hinzuzufügen, wenn es andere Möglichkeiten gibt, dies zu tun. Er sagt,

Overriding drawRect: verursacht einen Leistungseinbruch. Ich habe es nicht profiliert, , so dass ich nicht weiß, ob es eine erhebliche Leistung unter normalen Umständen ist (es ist wahrscheinlich nicht), aber in den meisten Fällen, Leute, die override drawRect: können erreichen, was sie wollen viel einfacher durch Einstellung Eigenschaften in der Ebeneneigenschaft einer Ansicht. Wenn Sie eine Kontur um einen Blick ziehen müssen, ist hier, wie Sie es tun würden:

#import <QuartzCore/QuartzCore.h> 

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.layer.borderWidth = 2.f; 
     self.layer.borderColor = [UIColor redColor].CGColor; 
    } 
    return self; 

Ich weiß, das wohl durchscheinen das Problem nicht von dem schwarzen Hintergrund lösen. Es ist nur etwas anderes zum Nachdenken.

1

Einstellung

opaque = false // NO for ObjC 

auf der Ansicht, löst das Problem.

+0

Dies ist die richtige Antwort. – Randy