Pregunta
¿Cómo puedo crear NSSlider animación al cambiar float valor de la misma.Yo estaba tratando de:
[[mySlider animator] setFloatValue:-5];
pero eso no funcionó..sólo cambiar el valor sin animación.Así que tal vez alguien sabe cómo hacer esto?
Gracias de antemano.
Solución
OK - así que esto no es tan rápido y bonito como esperaba, pero funciona. En realidad, no puede usar animadores y animación básica en la perilla deslizante, porque la animación básica solo funciona en capas y no hay acceso a los valores de la perilla en la capa deslizante.
Entonces, tenemos que recurrir en lugar de animar manualmente el valor del control deslizante. Ya que estamos haciendo esto en una Mac: puede usar nsanimation (que no está disponible en iOS).
Qué hace la nsanimación es simple: proporciona un mecanismo de sincronización / interpolación para permitirle animar (a diferencia de la animación básica que también se conecta a las vistas y maneja los cambios a ellos).
Para usar Nsanimation: más comúnmente lo subclascaría y anularíamos setCurrentProgress:
y ponga su lógica allí.
Así es como implementé esto, creé una nueva subclase de Nsanimation llamada 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
Para usarlo: simplemente crea un nuevo NSANIMATEFORSLIDER, déjalo en el control deslizante en el que está trabajando como delegado y antes de cada animación que configure es AnimateTovalue y luego inicie la animación.
Por ejemplo:
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];
Otros consejos
Su método funciona, pero hay algo mucho más simple.
Usted puede utilice el animador de proxy, usted sólo necesita saber cómo animarlo.Para hacer esto, usted necesita para implementar la defaultAnimationForKey:
método de la NSAnimatablePropertyContainer
protocolo.
Aquí está una subclase de NSSlider
que hace esto:
#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
Ahora usted puede simplemente utilizar el animador proxy:
[self.slider.animator setDoubleValue:100.0];
Asegúrese de enlace de la QuartzCore
marco.