6

更改浮点值时如何创建 NSSlider 动画。我在尝试:

[[mySlider animator] setFloatValue:-5];

但这不起作用..只需在没有动画的情况下更改值。所以也许有人知道该怎么做?

提前致谢。

4

2 回答 2

6

好的 - 所以这并不像我希望的那样快速和漂亮,但它确实有效。您实际上不能在滑块旋钮上使用动画师和核心动画 - 因为核心动画仅适用于图层,并且无法访问滑块图层中的旋钮值。

所以我们不得不求助于手动动画滑块值。由于我们在 Mac 上执行此操作 - 您可以使用NSAnimation(在 iOS 上不可用)。

NSAnimation 所做的很简单——它提供了一个计时/插值机制来允许你制作动画(与核心动画相反,它也连接到视图并处理对它们的更改)。

要使用 NSAnimation - 您通常会将其子类化并覆盖setCurrentProgress: 并将您的逻辑放在那里。

这是我实现它的方法 - 我创建了一个新的 NSAnimation 子类,名为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

要使用它 - 您只需创建一个新的 NSAnimationForSlider,将您正在处理的滑块作为委托给它,并在每个动画之前将其设置为 animateToValue,然后启动动画。

例如:

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];
于 2012-01-26T23:16:45.293 回答
3

您的方法有效,但有一些更简单的方法。

可以使用动画代理,您只需要告诉它如何制作动画即可。为此,您需要从协议中实现该defaultAnimationForKey:方法。NSAnimatablePropertyContainer


这是执行此操作的一个简单子类NSSlider

#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

现在您可以简单地使用动画代理:

[self.slider.animator setDoubleValue:100.0];

确保链接QuartzCore框架。

于 2013-10-24T18:00:23.763 回答