• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Wir haben den Frühjahrsputz beendet, Ihr auch? Welches Foto zu dem Thema hat Euch dann am Besten gefallen? Hier geht es lang zur Abstimmung --> Klick

NSBezierPath nachträglich verändern

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Hallo alle zusammen,

als Mac-Programmierneuling bin ich gerade dabei meine ersten Schritte zu machen. Da gehört natürlich auch Quartz dazu.

Jetzt versuche ich gerade, ein Würfel-Programm zu erstellen. Ein Button, feuert einen Zufallsgenerator und anschließend werden über NSBezierpath gezeichnete Kreise sichtbar oder unsichtbar gemacht, um die Augen eines Würfels nachzubilden.

Mein Problem ist, wie ich diese über eine for-Schleife generierten Objekte einzeln "ansteuere", da sie ja keine individuellen Namen haben. Oder werden die automatisch generiert?

Hier der Programmcode:
Code:
- (void)drawRect:(NSRect)dirtyRect {
    
	// Drawing code here.
	NSRect bounds = [self bounds];
	
    float fieldWith = bounds.size.width / 3.0;
    float fieldHeight = bounds.size.height / 3.0;
	int circleResizeFactor = -50;
	
	
	for (int x = 0; x < 3; x++)
    {
        for (int z = 0; z < 3; z++)
        {
            NSRect circleRect = NSMakeRect(fieldWith * z + (circleResizeFactor*-1)/2, fieldHeight * x + (circleResizeFactor*-1)/2, fieldWith + circleResizeFactor, fieldHeight + circleResizeFactor);
			
			[[NSColor blackColor] set];
			
			NSBezierPath *circlePath =[NSBezierPath bezierPathWithOvalInRect:circleRect];
			[circlePath fill];
		}
	}

Und ein Bild:
dice_gesamt.png

Sorry, wenn ich mich ein bisschen umständlich oder falsch ausdrücke, da ich ja, wie gesagt, blutiger Anfänger bin:innocent:

Danke für eure Antworten
Ludwig
 

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Ist die Frage echt so schwierig oder warum traut sich keiner zu Antworten? :(
 

babinet

Jonagold
Registriert
17.04.08
Beiträge
22
Du brauchst sie nicht erneut anzusteuern. Vielmehr überzeichnest du sie einfach jedes mal entsprechend.
 

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Hat also jedes NSRect einen eigenen Namen? Oder meinst du, dass ich die Gesamte for-Schleife bei einer neuen Zahl nochmal ausführen und den vorherigen Output überschreiben soll. Wird der dann automatisch gelöscht oder gibt's da extra eine was?

Dann hätte ich nämlich die Schwierigkeit zu unterscheiden welcher NSBezierPath je nach angezeigter Zahl sichtbar zu schalten oder unsichtbar zu lassen ist.

Ich müsste also in die for-Schleife eine if-Abfrage einbauen, die - bezogen auf die anzuzeigende Zahl und die Zählvariablen x und z - unterscheidet, ob ein Kreis gezeichnet werden soll oder nicht o_O

Geht das nicht auch einfacher, also z.B. indem ich erst die Punktmatrix zeichne und anschließend die Sichtbarkeit ändere oder gibt es eine Lösung, die nicht die for-Schleifen zum Zeichnen der Matrix benötigt und trotzdem so flexibel ist?

Vielen Dank!
Ludwig
 

Pii

Rheinischer Krummstiel
Registriert
25.06.07
Beiträge
383
Mach Dir einen CustomView für ein Würfelauge. Platziere diese X mal im InterfaceBuilder, und schalte diese nach Bedarf sichtbar.
 

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Danke für deine Idee! Also hat jeder Custom View dann eine Object id. Mit welcher funktion kann ich den dann sichtbar schalten?

Gibt es so eine Object id nicht auch für jeden erzeugten NSBezierPath?
 

babinet

Jonagold
Registriert
17.04.08
Beiträge
22
Natürlich gibt es die. Hier
NSBezierPath *circlePath =[NSBezierPath bezierPathWithOvalInRect:circleRect];
erzeugst du sie ja. Du müsstest Sie nur abspeichern, denn beim nächsten durchlauf der for-schleife wird circlepath ja überschrieben mit der Referenz auf einen neuen NSBezierPath.
Du kannst also alle 9 NSBezierPath abspeichern, z.B. als circlepath1, circlepath2, ... oder besser in einem Array und dann jedesmal wenn du neu zeichnen musst die passende Farbe setzen und [circlePath1 fill];[circlePath2 fill]; ... aufrufen.
Letztendlich gibt es dutzende Möglichkeiten das ganze zu lösen.
 

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Super! Genau das war es!
Ich kann jetzt bei jedem NSBezierpath eine andere Farbe setzten. Allerdings hab' ich noch das Problem, dass ich die NSBezierpath-Objekte nicht unsichtbar machen kann. Ich habs schon mit NSColor clearColor versucht, aber das geht leider nicht, da die Klasse NSBezierpath diese Farbe nicht unterstützt.

Habt ihr vielleicht eine Idee?
 

Pii

Rheinischer Krummstiel
Registriert
25.06.07
Beiträge
383
Also hat jeder Custom View dann eine Object id.
Alle Objekte habe eine id.
Du meinst wahrscheinlich eine Variable über die Du sie ansprichst.

Mit welcher funktion kann ich den dann sichtbar schalten?
Mit der Methode setHidden:. Schau mal in der Doku unter NSView nach.

Gibt es so eine Object id nicht auch für jeden erzeugten NSBezierPath?
Eine id haben sie alle.
Aber die Variable mit der Du arbeitest musst Du selbst setzen, und Du solltest sie nicht einfach wegschmeissen.
 

ludewig

Golden Delicious
Registriert
13.03.11
Beiträge
8
Ok, ich hab' jetzt mal das Programm auf meinen Kenntnisstand gebracht:

Die drawRect-Methode:

Code:
- (void)drawRect:(NSRect)dirtyRect {
    
	// Drawing code here.
	NSRect bounds = [self bounds];
	
    float fieldWidth = bounds.size.width / 3.0;
    float fieldHeight = bounds.size.height / 3.0;
	int circleResizeFactor = -50;
	
	
	circles = [[NSMutableArray alloc] init];
	
	
	for (int x = 0; x < 3; x++)
    {
        for (int z = 0; z < 3; z++)
        {
			
			
            NSRect circleRect = NSMakeRect(fieldWidth * z + (circleResizeFactor*-1)/2, fieldHeight * x + (circleResizeFactor*-1)/2, fieldWidth + circleResizeFactor, fieldHeight + circleResizeFactor);
			
			NSBezierPath *circlePath =[NSBezierPath bezierPathWithOvalInRect:circleRect];
			
			[[NSColor blackColor] set];
			[circlePath fill];
			
			[circles addObject:circlePath];
		}
	}
	[[circles objectAtIndex:0] setHidden:YES];
}

Leider öffnet sich das Programm dann nicht, sondern es erscheint der Fehler: Program received signal: "SIGABRT" und der Icon von meinem Programm hüpft im Dock wie wenn es starten würde.

Kann man mit setHidden: denn auch NSBezierpaths verstecken?

Gruß Ludwig
 

Pii

Rheinischer Krummstiel
Registriert
25.06.07
Beiträge
383
Kann man mit setHidden: denn auch NSBezierpaths verstecken?
Stammt NSBezierpaths vom NSView ab? Was steht denn in der Doku?

Ok, ich hab' jetzt mal das Programm auf meinen Kenntnisstand gebrach...

Nochmal: Mach Dir einfach einen View für das Würfelauge und platziere diese im IB.
Einzeln oder wenn Du willst hast auch als Matrix.

Dann brauchst Du für den View nur das bisschen Code:
Code:
- (void)drawRect:(NSRect)dirtyRect {
	[[NSColor blackColor] set];
	[[NSBezierPath bezierPathWithOvalInRect:[self bounds]] fill];
}

Die Views oder Matrix verbindest Du über Outlets, und schaltest diese nach Bedarf ein und aus.