首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSSlider动画

NSSlider动画
EN

Stack Overflow用户
提问于 2012-01-26 16:59:41
回答 2查看 1.8K关注 0票数 6

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

代码语言:javascript
复制
[[mySlider animator] setFloatValue:-5];

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

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-27 07:16:45

好的--这并不像我希望的那样快速和漂亮,但它是有效的。你不能在滑块旋钮上实际使用动画师和核心动画-因为核心动画只在层上工作,并且没有访问滑块层中的旋钮的值。

因此,我们不得不求助于手动设置滑块值的动画。因为我们是在Mac上做这件事,所以你可以使用NSAnimation (在iOS上是不可用的)。

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

要使用NSAnimation,最常见的做法是继承它的子类,重写setCurrentProgress:,并将逻辑放在其中。

下面是我如何实现它的--我创建了一个名为NSAnimationForSlider的新NSAnimation子类

NSAnimationForSlider.h:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
#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,然后开始动画。

例如:

代码语言:javascript
复制
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];
票数 6
EN

Stack Overflow用户

发布于 2013-10-25 02:00:24

您的方法是有效的,但还有一些简单得多的东西。

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

下面是NSSlider的一个简单的子类,它可以做到这一点:

代码语言:javascript
复制
#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

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

代码语言:javascript
复制
[self.slider.animator setDoubleValue:100.0];

确保链接QuartzCore框架。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9015767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档