我有一个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耗费大量内存......
答案 0 :(得分:15)
value
不起作用您显然找到了value
属性。检查文档,你会看到这句话
要渲染从当前值到新值的动画过渡,您应该使用
setValue:animated:
方法。
因此,正如文档中所说的那样使用
[aSlider setValue:player.currentTime animated:YES];
您松开手指时仅获得事件的原因是滑块不连续。来自continuous
属性的文档:
如果
YES
,滑块会持续向相关目标的操作方法发送更新事件。如果NO
,滑块仅在用户释放滑块的拇指控件以设置最终值时发送动作事件。
不,使用NSTimer动画这样的变化绝对不是最好的方法,我会说使用计时器是非常糟糕的做法。它不仅无效且可能不精确,而且还失去了对动画缓动的内置支持。
如果没有计时器你真的不能这样做,那么你应该至少使用CADisplayLink
代替NSTimer
。它可以用于UI更新(与NSTimer相反,而不是)。
答案 1 :(得分:5)
你应该使用这些:
创建滑块时将滑块属性continuous
设置为YES
aSlider.continuous = YES;
使用setValue:animated
方法,
[aSlider setValue:player.currentTime animated:YES];
答案 2 :(得分:3)
我一直在寻找一个解决方案,我在UISlider
添加一个目标,当用户停止移动滑块时,只会触发一次。
我想保存一次选择的值而不是每次更新,这就是为什么我使用continous
取消NO
的原因。我刚刚意识到,设置为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];
}
}];
}
也许有人可以使用它!