Questo tipo di problema è meglio risolti con una NSTimer anziché la funzione animatore:
Sia la chiamata timer una funzione ripetutamente, finché l'animazione è "completo". Al termine, termina il timer (invalido).
La funzione da chiamare ripetutamente in ciascun ciclo afferra la framesize effettivo della finestra e la framesize effettiva di immagine e semplicemente aggiunge il terzo della differenza dei due al telaio della vista, come:
frame.size.height += diffHeight/3.0;
Quindi, indipendentemente da ciò che accade, la vista cresce o si restringe sempre più vicino alla sua destinazione. Una volta che l'add (della differenza) è inferiore ad es. 0.2 imposta la vista direttamente alla dimensione desiderata e termina il timer. Questo è diretto, usa solo un piccolo codice e non è necessario ascoltare gli eventi mentre funziona abbastanza bene. :-)
Qui ci sono i codici fondamentali per initiallize l'animazione (timer deve essere un'istanza della classe):
if(timer)return;
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(resizeView:) userInfo:[NSNumber numberWithBool:status] repeats:YES];
[timer setTolerance:0.02];
Io uso la parola di stato al posto della tua parola chiusa, la funzione di essere ripetutamente chiamato potrebbe quindi somigliare a:
- (void)resizeView:(id)userInfo;
{
BOOL status = [(NSNumber *)[userInfo userInfo] boolValue];
double startwid,stopwid;
NSRect newSizeRect = [[self window] frame];
stopwid = newSizeRect.size.width;
if(status){
stopwid -= 100.0;
}
NSRect cbgRect = [self frame];
startwid = cbgRect.size.width;
double diff = stopwid-startwid;
if(fabs(diff)<0.2){
diff = 0;
startwid = stopwid;
[timer invalidate];
timer = nil;
//NSLog(@"stop");
}
//NSLog(@"%f - %f = %f /10 = %f",stopwid,startwid,diff,diff/3.0);
cbgRect.size.width = startwid+diff/3.0;
[self setFrame:cbgRect];
}