user1843954
user1843954

Reputation: 31

UISlider not updating

I am trying to code a music player for an assignment and I am stuck with trying to get the slider to update as the song is playing. I have been able to make it so that if the user were to slide the slider the song will rewind/fast-forward to that part of the song. Does anyone know why the slider doesn't continuously update as the song is playing?

Here is the .h file

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

@interface AS3MPViewController : UIViewController <MPMediaPickerControllerDelegate>{
    IBOutlet UIButton *playButton;
    IBOutlet UIButton *stopButton;
    IBOutlet UIButton *pauseButton;
    IBOutlet UISlider *volumeSlider;
    AVAudioPlayer *musicPlayer;
    IBOutlet UIButton *pickSongButton;
    IBOutlet UISlider *timeSlider;
    NSTimer *timer;
}

@property (nonatomic, retain) UIButton *playButton;
@property (nonatomic, retain) UIButton *stopButton;
@property (nonatomic, retain) UIButton *pauseButton;
@property (nonatomic, retain) UISlider *volumeSlider;
@property (nonatomic, retain) AVAudioPlayer *musicPlayer;
@property (nonatomic, retain) UIButton *pickSongButton;
@property (nonatomic, retain) UISlider *timeSlider;
@property (nonatomic, retain) NSTimer *timer;

- (IBAction) play;
- (IBAction) stop;
- (IBAction) pause;
- (IBAction) changeVolume: (UISlider *)sender;
- (IBAction) chooseSong: (UIButton *)sender;
- (IBAction) changeTime: (UISlider *)sender;
- (void)setTimeSliderOptions;

@end

Here is the .m file

#import "AS3MPViewController.h"

@interface AS3MPViewController ()

@end

@implementation AS3MPViewController

@synthesize playButton = _playButton;
@synthesize stopButton = _stopButton;
@synthesize pauseButton = _pauseButton;
@synthesize musicPlayer = _musicPlayer;
@synthesize volumeSlider = _volumeSlider;
@synthesize pickSongButton = _pickSongButton;
@synthesize timeSlider = _timeSlider;
@synthesize timer;

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"animals001"     ofType:@"mp3"];

    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];

    self.musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];

    [self.musicPlayer prepareToPlay];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction) play {
    [self.musicPlayer play];

}

- (IBAction) stop {
    [self.musicPlayer stop];
    self.musicPlayer.currentTime = 0;
}

- (IBAction) pause {
    [self.musicPlayer pause];
}

- (IBAction) changeVolume: (UISlider *)sender {
    self.musicPlayer.volume = [sender value];
}

- (IBAction)chooseSong:(UIButton *)sender {
    MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];

    [mediaPicker setDelegate:self];
    [mediaPicker setAllowsPickingMultipleItems:NO];

    mediaPicker.prompt = NSLocalizedString(@"Add Some Songs To Play", "Prompt In Media Item Picker");

    [self presentModalViewController: mediaPicker animated:YES];
}

- (void) mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
[self dismissModalViewControllerAnimated:YES];
}

- (void) mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:    (MPMediaItemCollection *)mediaItemCollection {

    MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0];
    NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];

    //AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
    //AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

    self.timeSlider.maximumValue = [self.musicPlayer duration];

    self.musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

    [self.musicPlayer play];

    timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(songCurrentTime) userInfo:nil repeats:YES];

    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)changeTime: (UISlider *)sender {
    self.musicPlayer.currentTime = self.musicPlayer.duration * sender.value;
}

- (void)songCurrentTime {
    timeSlider.value = (self.musicPlayer.currentTime / self.musicPlayer.duration);
}
@end

Upvotes: 3

Views: 1900

Answers (7)

user1039695
user1039695

Reputation: 1061

There was transparent view over my UISlider in my case and i was overlooking in to it.

Upvotes: 0

guru
guru

Reputation: 2817

For me the issue was different i need to set initial value to slider, but it was a silly mistake that i am updating slider value before setting maximum and minimum value.

Wrong code :

float value = [self getSliderDefaultValue];
[slider setValue:value animated:NO];
slider.maximumValue = numberOfSteps;
slider.minimumValue = 0;

Working code :

slider.maximumValue = numberOfSteps;
slider.minimumValue = 0;
float value = [self getSliderDefaultValue];
[slider setValue:value animated:NO];

Hope it will help others!!!

Upvotes: 0

ashokdy
ashokdy

Reputation: 1001

check in the connections that you are connected the IBAction method with slider with ValueChanged EX:

- (IBAction)changeTime: (UISlider *)sender {

check whether this method is connected with ValueChanged while IB connection

Upvotes: 2

Somebody
Somebody

Reputation: 11

I think your problem is that you are updating the value of the slider from a thread other than the main one. Try modifying the songCurrentTime method so that it calls another one on the main thread that updates the value of the slider.

- (void)songCurrentTime {
[self performSelectorOnMainThread:@selector(songCurrentTimeMain) withObject:nil waitUntilDone:YES];
}

- (void)songCurrentTimeMain {
timeSlider.value = (self.musicPlayer.currentTime / self.musicPlayer.duration);
}

Of course to get correct results make sure the minimum value of the slider is 0 and the maximum is 1.

Best Regards

Upvotes: 1

Phillip Mills
Phillip Mills

Reputation: 31016

timeSlider and self.timeSlider are not the same thing. Most of the iVars that you have declared are unnecessary (and misleading) because you synthesize your properties using the underscore form of the property name. For example, you have a timeSlider property that's backed by a _timeSlider iVar, and a timeSlider iVar that's a different thing entirely.

Use self.timeSlider.value = ....

Upvotes: 0

danielM
danielM

Reputation: 2512

When you set your slider value, the value is always less than or equal to 1 because self.musicPlayer.currentTime is always less than or equal to self.musicPlayer.duration. Instead, try this

timeSlider.value = self.musicPlayer.currentTime;

Upvotes: 0

Sanjin Haracic
Sanjin Haracic

Reputation: 73

I've done something similar within this tutorial and the way I added a slider was the same as you did except for the fact that I used

musicPlayer.currentPlaybackTime

as a value to assign to the slider.

It may be that the result of (self.musicPlayer.currentTime / self.musicPlayer.duration) is an inaccurate assignment to your slider value.

Upvotes: 0

Related Questions