Hi,
ich habe das Problem das sich meine NSView Subklasse nicht neu zeichnet.
Folgende Ausgangssituation:
- Ein View dient zur Visualisierung gewisser Griffpunkte auf einem Bass (jaja, das alte Leid ;))
- Die Griffpunkte um eine Note zu spielen werden angezeigt für eine Note, repräsentiert durch ein int
- In dem Controller wird ein NSTimer gescheduled der alle 4 Sekunden eine Methode auslöst die eine neue Note (neue int) auswählt, diese anzeigen lässt (kann man bestimmt eleganter mit Bindings lösen) , und der NSView Subklasse mitteilt das sie sich neu zeichnen soll
- Die überschriebene drawRect: enthält ein switch auf die gesetzte Note, um herauszufiltern welche Punkte es zusätzlich zum Hintergrund zeichnen soll
Abgesehen davon das der Code miese Methodennamen enthält und generell eher einem unsortierten Haufen Müll gleicht (eine langweilige Englischvorlesung war die Geburtsstunde dieses ganzen Codes) musste ich am Ende feststellen das mein Code sich sämtlichen Versuchen verweigert seine drawRect: Methode neu auszulösen (indirekt, also nicht durch Aufruf von drawRect:). Das habe ich durch debuggen herausgefunden, da mein Breakpoint in der drawRect: Methode nur einmal (zu Beginn) erreicht wird.
Meine Theorie ist das sich dadurch, das sämtlche Änderungen/Aufrufe an das NSView über die im Timer geschedulte Methode ereignen, die display oder setNeedsDisplay: Methoden wirkungslos bleiben, da es Probleme mit dem Event Loop gibt, weil der NSTimer eventuell einen zweiten Thread gespawned hat und Cocoa sich deshalb verheddert?! Hoffe das war nachvollziehbar formuliert.
Hier noch die meiner Meinung beteiligten Methoden.
Alles anzeigen
Für Hinweise was ich alles falsch mache wäe ich sehr dankbar!
ich habe das Problem das sich meine NSView Subklasse nicht neu zeichnet.
Folgende Ausgangssituation:
- Ein View dient zur Visualisierung gewisser Griffpunkte auf einem Bass (jaja, das alte Leid ;))
- Die Griffpunkte um eine Note zu spielen werden angezeigt für eine Note, repräsentiert durch ein int
- In dem Controller wird ein NSTimer gescheduled der alle 4 Sekunden eine Methode auslöst die eine neue Note (neue int) auswählt, diese anzeigen lässt (kann man bestimmt eleganter mit Bindings lösen) , und der NSView Subklasse mitteilt das sie sich neu zeichnen soll
- Die überschriebene drawRect: enthält ein switch auf die gesetzte Note, um herauszufiltern welche Punkte es zusätzlich zum Hintergrund zeichnen soll
Abgesehen davon das der Code miese Methodennamen enthält und generell eher einem unsortierten Haufen Müll gleicht (eine langweilige Englischvorlesung war die Geburtsstunde dieses ganzen Codes) musste ich am Ende feststellen das mein Code sich sämtlichen Versuchen verweigert seine drawRect: Methode neu auszulösen (indirekt, also nicht durch Aufruf von drawRect:). Das habe ich durch debuggen herausgefunden, da mein Breakpoint in der drawRect: Methode nur einmal (zu Beginn) erreicht wird.
Meine Theorie ist das sich dadurch, das sämtlche Änderungen/Aufrufe an das NSView über die im Timer geschedulte Methode ereignen, die display oder setNeedsDisplay: Methoden wirkungslos bleiben, da es Probleme mit dem Event Loop gibt, weil der NSTimer eventuell einen zweiten Thread gespawned hat und Cocoa sich deshalb verheddert?! Hoffe das war nachvollziehbar formuliert.
Hier noch die meiner Meinung beteiligten Methoden.
Quellcode
- // Im View
- - (void)drawNote:(int)note {
- _note = note;
- NSLog(@"New note is %i", _note);
- // meiner Meinung nach logische Position und logischer Aufruf, habe auch andere Varianten probiert
- [self display];
- }
- - (void)drawRect:(NSRect)rect
- {
- [NSGraphicsContext saveGraphicsState];
- NSRect frameRect = [self frame];
- NSBezierPath* path = [NSBezierPath bezierPath];
- // Zeichencode
- NSBezierPath* noteDots = [NSBezierPath bezierPath];
- NSLog(@"Should draw note %i", _note);
- if(_note != -1) {
- NSLog(@"Should draw an e");
- float s = (frameRectQuarter/2);
- [self drawEInPath:noteDots usingStringSpacing:s andBarDistance:0.0];
- switch(_note) {
- case 0:
- /*[noteDots moveToPoint:NSMakePoint(21.0, frameRectQuarter/2)];
- [noteDots appendBezierPathWithArcWithCenter:NSMakePoint(21.0, frameRectQuarter/2)
- radius:7
- startAngle:0.0
- endAngle:360.0];
- */break;
- // cas 1,2,3, usw
- default:
- break;
- }
- }
- //Zeichencode
- [NSGraphicsContext restoreGraphicsState];
- }
- // Im Controller
- - (IBAction)displayNextNote:(id)sender
- {
- [self displayNotes:nil];
- if(timer == nil)
- timer = [[NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(displayNotes:) userInfo:nil repeats:YES] retain];
- [spinner startAnimation:nil];
- }
- - (void)displayNotes:(id)args {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- srandom([[NSDate date] timeIntervalSince1970]);
- int rand = -1;
- do {
- rand = (random() % noteCount);
- } while(rand == lastNote);
- lastNote = rand;
- NSString* currentNote = [notesOnBass objectAtIndex:rand];
- [note setStringValue:currentNote];
- [tabs drawNote:rand];
- [tabs setNeedsDisplay:YES];
- [pool release];
- }
Für Hinweise was ich alles falsch mache wäe ich sehr dankbar!