首页 文章

UISlider平滑地改变 Value

提问于
浏览
6

我有一个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耗费大量内存......

3 回答

  • 3

    为什么设置动画值不起作用

    你显然找到了 value 属性 . 检查文档,你会看到这句话

    要渲染从当前值到新值的动画过渡,您应该使用setValue:animated:方法 .

    所以,正如文档所说的那样

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

    为什么只有在释放手指时才能获得事件

    释放手指时仅获取事件的原因是滑块不连续 . 从 continuous 属性的文档:

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

    NSTimer不是最好的方法

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

    如果你真的不能没有计时器,那么你应该至少使用 CADisplayLink 而不是 NSTimer . 它可以用于UI更新(与NSTimer不同) .

  • 5

    你应该使用这些:

    • 创建滑块时将滑块属性 continuous 设置为 YES

    在你的情况 aSlider.continuous = YES;

    • 使用 setValue:animated 方法,

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

  • 15

    我正在寻找一个解决方案,我将一个目标添加到我的 UISlider ,只有当用户停止移动滑块时才会触发一次 .

    我想保存一次选择的值而不是每次更新,这就是为什么我用 NO 删除了 continous . 我刚刚意识到,设置为NO将不再为滑块设置动画 . 所以经过一些尝试,我发现,如果你将 self.slider setValue:animated:[UIView animateWithDuration:animations:] 结合使用, UISlider 将会被动画化,如下所示:

    Add the target

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

    Target method

    - (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];
            }
        }];
    }
    

    也许有人可以用这个!

相关问题