自定义UISlider,如音乐应用程序 [英] Custom UISlider like the Music app
问题描述
我已经制作了一个自定义滑块来显示音乐曲目播放的进度并允许在曲目中进行清理。
I've built a custom slider to show the progress of a music track playing and to allow scrubbing within the track.
两种功能都很好,但拖动停止并重新定位滑块后会出现轻微滞后(和跳动) - Apple Music应用程序滑块是无缝的。
Both function fine, but there is a slight lag (and jumpy movement) once dragging has stopped and the slider is repositioned - The Apple Music app slider is seamless.
_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
推荐答案
经过大量的记录后 - 我发现UISlider组件有一个轻微的滞后更新 - 在1/10到3/10秒之间 - 导致跳跃。
After alot of logging - I found that the UISlider component had a slight lag updating itself - between 1/10 and 3/10s of a second - which caused the jump.
我还将计时器间隔更改为0.5秒,我还通过在< savedValue
变量来帮助更新code> ScrubberSlider 和BOOL hasFinishedMoving
,所以 beginTrackingWithTouch
endTrackingWithTouch
ScrubberSlider中的方法如下所示:
I also changed the timer interval to 0.5 seconds and I also helped the update with adding a savedValue
variable inside ScrubberSlider
and a BOOL hasFinishedMoving
, so the beginTrackingWithTouch
endTrackingWithTouch
methods inside ScrubberSlider looks like this:
-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super beginTrackingWithTouch:touch withEvent:event];
_hasFinishedMoving = NO;
return YES;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
_savedValue = self.value;
_hasFinishedMoving = YES;
}
并更改 updatePosition
包含这些变量和验证:
and changed the updatePosition
to include these vars and validations:
-(void) updatePosition
{
if (!_scrubberSlider.tracking) // this is a UISlider BOOL
{
if (_scrubberSlider.hasFinishedMoving)
{
_scrubberSlider.value = _scrubberSlider.savedValue;
_scrubberSlider.hasFinishedMoving = NO;
}
else
{
CGFloat percent = _theMusicPlayer.currentPlaybackTime / [[_theMusicPlayer.nowPlayingItem valueForKey:MPMediaItemPropertyPlaybackDuration] floatValue];
_scrubberSlider.value = percent;
}
}
}
这篇关于自定义UISlider,如音乐应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!