2012-01-26 19 views
5

Come posso creare un'animazione NSSlider quando si modifica il valore float di esso. Stavo cercando:Animazione NSSlider

[[mySlider animator] setFloatValue:-5]; 

ma che non ha funzionato .. basta cambiare il valore senza animazione. Quindi forse qualcuno sa come farlo?

Grazie in anticipo.

risposta

5

Ok, quindi non è così veloce e bello come speravo ma funziona. Non è possibile utilizzare animatori e Core Animation nella manopola di scorrimento, poiché Core Animation funziona solo sui livelli e non è possibile accedere ai valori della manopola nel livello di scorrimento.

Quindi dobbiamo ricorrere invece all'animazione manuale del valore del cursore. Dato che lo stiamo facendo su un Mac, puoi usare NSAnimation (che non è disponibile su iOS).

Ciò che NSAnimation fa è semplice: fornisce un meccanismo di temporizzazione/interpolazione che consente all'utente di animare (al contrario dell'anima core che si collega anche alle viste e ne gestisce le modifiche).

Per utilizzare NSAnimation, lo si dovrebbe in genere sottoclasse e sostituisce setCurrentProgress: e inserisce la logica.

Ecco come ho implementato questo - ho creato una nuova sottoclasse NSAnimation chiamato NSAnimationForSlider

NSAnimationForSlider.h:

@interface NSAnimationForSlider : NSAnimation 
{ 
    NSSlider *delegateSlider; 
    float animateToValue;  
    double max; 
    double min; 
    float initValue; 
} 
@property (nonatomic, retain) NSSlider *delegateSlider; 
@property (nonatomic, assign) float animateToValue;  
@end 

NSAnimationForSlider.m:

#import "NSAnimationForSlider.h" 

@implementation NSAnimationForSlider 
@synthesize delegateSlider; 
@synthesize animateToValue; 

-(void)dealloc 
{ 
    [delegateSlider release], delegateSlider = nil; 
} 

-(void)startAnimation 
{ 
    //Setup initial values for every animation 
    initValue = [delegateSlider floatValue]; 
    if (animateToValue >= initValue) { 
     min = initValue; 
     max = animateToValue; 
    } else { 
     min = animateToValue; 
     max = initValue; 
    } 

    [super startAnimation]; 
} 


- (void)setCurrentProgress:(NSAnimationProgress)progress 
{ 
    [super setCurrentProgress:progress]; 

    double newValue; 
    if (animateToValue >= initValue) { 
     newValue = min + (max - min) * progress;   
    } else { 
     newValue = max - (max - min) * progress; 
    } 

    [delegateSlider setDoubleValue:newValue]; 
} 

@end 

Per utilizzarlo - è sufficiente crea un nuovo NSAnimationForSlider, dagli il cursore su cui stai lavorando come delegato e prima di ogni animazione impostalo come animateToValue e poi inizia l'animazione.

Ad esempio:

slider = [[NSSlider alloc] initWithFrame:NSMakeRect(50, 150, 400, 25)]; 
[slider setMaxValue:200]; 
[slider setMinValue:50]; 
[slider setDoubleValue:50]; 

[[window contentView] addSubview:slider]; 

NSAnimationForSlider *sliderAnimation = [[NSAnimationForSlider alloc] initWithDuration:2.0 animationCurve:NSAnimationEaseIn]; 
[sliderAnimation setAnimationBlockingMode:NSAnimationNonblocking]; 
[sliderAnimation setDelegateSlider:slider]; 
[sliderAnimation setAnimateToValue:150]; 

[sliderAnimation startAnimation]; 
+0

Grazie per la risposta, forse si può dire più preciso come farlo?perché non ho capito esattamente cosa intendi. Cosa intendi per dire animazione di base? "animatore" penso sia l'animazione di base. –

+0

Presto sarò sul mio desktop e cercherò di scriverlo in codice per te – shein

+0

ok, grazie mille! Aspetterò. –

2

vostro metodo funziona, ma c'è qualcosa di molto più semplice.

È possibile utilizzare il proxy animatore, devi solo dirgli come animarlo. Per fare ciò, è necessario implementare il metodo defaultAnimationForKey: dal protocollo NSAnimatablePropertyContainer.


Ecco un semplice sottoclasse di NSSlider che fa questo:

#import "NSAnimatableSlider.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation NSAnimatableSlider 

+ (id)defaultAnimationForKey:(NSString *)key 
{ 
    if ([key isEqualToString:@"doubleValue"]) { 
     return [CABasicAnimation animation]; 
    } else { 
     return [super defaultAnimationForKey:key]; 
    } 
} 

@end 

Ora si può semplicemente utilizzare il proxy animatore:

[self.slider.animator setDoubleValue:100.0]; 

Assicurarsi di collegare il QuartzCore struttura.

+1

Secondo [questo esempio di Apple] (https://developer.apple.com/library/mac/samplecode/AnimatedSlider/Listings/AnimatedSlider_NSSliderExtensions_m.html#//apple_ref/doc/uid/DTS10000378-AnimatedSlider_NSSliderExtensions_m-DontLinkElementID_6), tu può anche abilitare questo con un'estensione di classe. Ma la sottoclasse ha meno probabilità di interferire con altri codici. – DarkDust