7

我有一个 UIslider 设置 AVAdioRecording 的位置:

CGRect frame = CGRectMake(50.0, 230.0, 200.0, 10.0);
                     aSlider = [[UISlider alloc] initWithFrame:frame];
                     // Set a timer which keep getting the current music time and update the UISlider in 1 sec interval
                     sliderTimer = [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];
                     // Set the maximum value of the UISlider
                     aSlider.maximumValue = player.duration;
                     // Set the valueChanged target
                     [aSlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
                     [self.ViewA addSubview:aSlider];




 - (void)updateSlider {
// Update the slider about the music time

[UIView beginAnimations:@"returnSliderToInitialValue" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:1.3];

aSlider.value = player.currentTime;

[UIView commitAnimations];
}

- (IBAction)sliderChanged:(UISlider *)sender {
// Fast skip the music when user scroll the UISlider
[player stop];
[player setCurrentTime:aSlider.value];
[player prepareToPlay];
[player play];
}

我想问三个问题。

1)为什么值变化的动画不起作用?2) 为什么只有当我手指从按钮上松开而不跟随时,滑块位置才会移动?3) 使用 NSTimer 是最好的方法吗?我听说 NSTimer 非常消耗内存...

4

3 回答 3

16

为什么动画value不起作用

您显然找到了该value物业。查看文档,你会看到这句话

要呈现从当前值到新值的动画过渡,您应该改用该setValue:animated:方法。

所以,正如文档所说使用

[aSlider setValue:player.currentTime animated:YES];

为什么只有松开手指时才会收到事件

当您松开手指时您只收到事件的原因是您的滑块不连续。从continuous财产的文件:

如果YES,滑块将更新事件连续发送到关联目标的操作方法。如果NO,则滑块仅在用户释放滑块的拇指控件以设置最终值时发送一个动作事件。

NSTimer不是最好的方法

不,使用 NSTimer 为这样的更改设置动画绝对不是最好的方法,我会说使用计时器是非常糟糕的做法。它不仅无效且可能不精确,而且您还会失去对缓动动画的内置支持。

如果你真的不能在没有计时器的情况下做到这一点,那么你至少应该使用 aCADisplayLink而不是 a NSTimer。它适用于 UI 更新(与 NSTimer 不同)。

于 2013-09-15T13:33:38.857 回答
5

您可能应该使用这些:

  1. 将滑块属性设置continuousYES创建滑块时,

    在你的情况下 aSlider.continuous = YES;

  2. 使用setValue:animated方法,

    在你的情况下 [aSlider setValue:player.currentTime animated:YES];

于 2013-09-15T13:33:04.293 回答
4

我正在寻找一种解决方案,在其中添加一个目标,UISlider当用户停止移动滑块时,该目标只会被触发一次。

我想保存一次选择的值,而不是每次更新,这就是我取消选择continous的原因NO。我刚刚意识到,将 continous 设置为 NO 将不再为滑块设置动画。所以经过一些尝试,我发现,如果你像这样结合UISlider使用,将会动画:self.slider setValue:animated:[UIView animateWithDuration:animations:]

添加目标

[self.sliderSkill addTarget:self 
                     action:@selector(skillChange) 
           forControlEvents:UIControlEventValueChanged];

目标方法

- (void)skillChange{

    CGFloat fValue = self.sliderSkill.value;

    [UIView animateWithDuration:0.5f animations:^{
        if( fValue < 1.5f ){
            [self.slider setValue:1 animated:YES];
        } else if( fValue > 1.5f && fValue < 2.5f ){
            [self.slider setValue:2 animated:YES];
        } else {
            [self.slider setValue:3 animated:YES];
        }
    }];
}

也许有人可以使用这个!

于 2015-06-11T10:31:41.257 回答