2012-09-13 4 views
9

Ich habe eine leere Cocoa-Anwendung auf Xcode für OS X und fügte hinzu:Wie macht NSView seinen Begrenzungsbereich nicht abschneiden?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    self.view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 200, 200)]; 
    self.view.wantsLayer = YES; 
    self.view.layer = [CALayer layer]; 
    self.view.layer.backgroundColor = [[NSColor yellowColor] CGColor]; 
    self.view.layer.anchorPoint = CGPointMake(0.5, 0.5); 
    self.view.layer.transform = CATransform3DMakeRotation(30 * M_PI/180, 1, 1, 1); 

    [self.window.contentView addSubview:self.view]; 
} 

Aber der Hintergrund der gedrehten Schicht wird durch die Ansicht der Begrenzungsbereich abgeschoren

enter image description here

ich da einige gedacht Version von OS X und iOS, wird die Ansicht nicht den Inhalt der Unteransichten abschneiden und alles innerhalb und außerhalb zeigen? Auf iOS sehe ich dieses Verhalten, aber ich frage mich, warum es so auftaucht und wie man alles zeigen lässt? (Ich verwende bereits den aktuellsten Xcode 4.4.1 auf Mountain Lion).

(Anmerkung: Wenn Sie den Code oben versuchen, müssen Sie Quarz-Kern verbinden, und möglicherweise den Quarzkern-Header importieren, obwohl ich frage mich, warum ich nicht den Header nicht einführten und es kompiliert noch perfekt)

Antwort

10

es stellt sich heraus, dass, wenn die Zeile:

((NSView *)self.window.contentView).wantsLayer = YES; 

an den Anfang hinzugefügt wird, dann funktioniert es wie erwartet:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    ((NSView *)self.window.contentView).wantsLayer = YES; 

    self.view = [[NSView alloc] initWithFrame:NSMakeRect(200, 200, 200, 200)]; 

    self.view.wantsLayer = YES; 

    self.view.layer.backgroundColor = [[NSColor yellowColor] CGColor]; 

    [self.window.contentView addSubview:self.view]; 
    self.view.layer.anchorPoint = CGPointMake(0.5, 0.5); 

    self.view.layer.transform = CATransform3DMakeRotation(30 * M_PI/180, 0, 0, 1); 

} 

so wie es aussieht, wenn alle Ansichten gemacht werden um Layer-Backed zu sein, funktioniert es genauso wie auf iOS. (Wenn es einen schnellen Weg gibt, alle Ansichten automatisch zu sichern, wäre das gut).

Die anchorPoint Zeile kann nicht vor addSubview Zeile verschoben werden, sonst ist es falsch, obwohl ich mich frage, warum das einen Unterschied machen würde.

Die Zeile self.view.layer = [CALayer layer]; kann entfernt werden, wenn window.contentView Layer-Backed ist. Sowohl contentView als auch self.view müssen die Ebene nicht festlegen, und ich frage mich auch warum.

Die transform Linie kann nicht vor der addSubview Linie sein, sonst wird es nicht drehen, und ich frage mich warum auch.

Die dritte Sache ist, dass ich dachte, wenn ich gehe Builder-Schnittstelle und die content eine Klasse von ContentView zu machen (Subklassen NSView) und in seiner init Methode, mache ein self.wantsLayer = YES;, dann auch, es würde funktionieren, aber es funktioniert nicht.

Aber wie auch immer, der Code oben funktioniert, und ich werde die Gründe oben warum aktualisieren, wenn ich mehr herausfinden.

enter image description here

+0

Ich bin ein iOS-Entwickler, und ich habe vor kurzem begonnen, in Cocoa arbeiten. Das hat mich die letzten drei Tage verrückt gemacht. Ich bin überrascht, dass ich nicht mehr Informationen darüber finden kann. Danke, dass du deine Lösung gepostet hast !! – KevinM

+0

Es kann Probleme geben, wenn Sie NSView mit Ebenen und Ebenen ohne Ebenen mischen. Es ist nicht stabil, welcher Inhalt den anderen überlagert wird. – Slavik

+1

Das Setzen von 'self.wantsLayer = YES' funktioniert nicht in' init', weil 1. der richtige Initialisierer 'initWithFrame:' ​​ist und 2. selbst das für Aufrufe, die von nibs geladen werden, nicht aufgerufen wird. Sie sollten '-awakeFromNib' überschreiben und dort Ihre Einstellungen vornehmen. Alternativ können Sie die Core-Animation-Layer-Eigenschaft im Inspection-Effekt-Inspektor von IB festlegen. –