我构建了一个自定义滑块来显示音乐曲目播放的进度并允许在曲目内进行擦洗。
两者都运行良好,但一旦停止拖动并且重新定位滑块,就会出现轻微的滞后(和跳跃的运动) - Apple Music 应用程序滑块是无缝的。
_scrubberSlider = [[ScrubberSlider alloc] initWithFrame:CGRectMake(0, 0, 300, 30)];
_scrubberSlider.continuous = YES;
_scrubberSlider.maximumValue = 1.0f;
_scrubberSlider.minimumValue = 0.0f;
[_scrubberSlider addTarget:self action:@selector(handleSliderMove:) forControlEvents:UIControlEventValueChanged];
- (void) handleSliderMove:(UISlider*)sender
{
CGFloat currentPlayback = sender.value * [[_theMusicPlayer.nowPlayingItem valueForKey:MPMediaItemPropertyPlaybackDuration] floatValue];
_theMusicPlayer.currentPlaybackTime = currentPlayback;
}
-(void) handleTrackTime
{
if (!trackTimer)
{
NSNumber *playBackTime = [NSNumber numberWithFloat: _musicPlayer.currentPlaybackTime];
trackTimer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(timeIntervalFinished:) userInfo:@{@"playbackTime" : playBackTime} repeats:YES];
}
}
-(void) timeIntervalFinished:(NSTimer*)sender
{
[self playbackTimeUpdated:_musicPlayer.currentPlaybackTime];
}
-(void) playbackTimeUpdated:(CGFloat)playbackTime
{
// Update time label
[self updatePosition];
}
-(void) updatePosition
{
if (!_scrubberSlider.isScrubbing)
{
CGFloat percent = _theMusicPlayer.currentPlaybackTime / [[_theMusicPlayer.nowPlayingItem valueForKey:MPMediaItemPropertyPlaybackDuration] floatValue];
_scrubberSlider.value = percent;
}
}
自定义滑块
@interface ScrubberSlider : UISlider
@property(nonatomic) BOOL isScrubbing;
@end
@implementation ScrubberSlider
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super beginTrackingWithTouch:touch withEvent:event];
_isScrubbing = YES;
return YES;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
_isScrubbing = NO;
}
@end
也许你的处理方式是错误的。不要尝试与赛道时间完全同步(这会导致一些非常糟糕的比赛条件,这正是滑块在“抛出”而不是拖动、按住然后释放时无法正确更新的原因),而是尝试使用您拥有的计时器作为“滴答声”。您可以将射速降低到每半秒一次,然后使用与现在基本相同的逻辑,但不要尝试在-updatePosition
,您向前“勾选”滑块。
-(void) updatePosition
{
if (!_scrubberSlider.isScrubbing)
{
_scrubberSlider.value += .5f;
}
}
它并不完美,但话又说回来,它比尝试使用 NSTimer 将自己同步到音乐曲目的时间(对于精确的运动来说可能非常不准确)要高效和无缝得多。这还要求滑块的最大值等于轨道的最大值,因此开始播放的示例方法将包括如下内容:
- (IBAction)startPlayback:(id)sender {
//... Handle however you wish to play the track
_scrubberSlider.maximumValue = [[_theMusicPlayer.nowPlayingItem valueForKey:MPMediaItemPropertyPlaybackDuration] floatValue];
[self handleTrackTime];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)