user53789
user53789

Reputation: 11

Is there a general template for creating a UIPickerview which selects short sound files?

Is there a general template or tutorial or web page that describes the procedure for creating a UIPickerview which selects short sound files and plays them upon selection or with a player? Thanks

Upvotes: 1

Views: 1920

Answers (1)

Noah Witherspoon
Noah Witherspoon

Reputation: 57139

You'll need a delegate/data-source class for your picker view - something that implements the protocols UIPickerViewDelegate and UIPickerViewDataSource. This can be whatever view controller you've got handling everything else or a separate class - either way, set the UIPickerView's delegate and dataSource properties to your instance of that class.

The class should have three instance variables - an NSArray soundArr to contain the sounds, an NSTimer timer to provide a delay after selection before the sound plays (more on that below), and an AVAudioPlayer audioPlayer to play the selected sound (for which you'll need to import the AVFoundation framework - it's only available in 2.2, as sound playback used to be a lot more complicated).

When you first load the sounds (in your controller class's -init method or whatever), stick 'em in an array along with the title you want them to display, something like this:

NSBundle *bdl = [NSBundle mainBundle];
soundArr = [[NSArray alloc] initWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"Sound One",@"title",[NSURL URLWithString:[bdl pathForResource:@"sound1" ofType:@"wav"]],@"url",nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"Sound Two",@"title",[NSURL URLWithString:[bdl pathForResource:@"sound2" ofType:@"wav"]],@"url",nil],
nil];

The methods you'll need to implement are:

  • -pickerView:numberOfRowsInComponent: - should return the size of soundArr
  • -pickerView:titleForRow:forComponent: - should return [[soundArr objectAtIndex:row] objectForKey:@"title"]
  • -numberOfComponentsInPickerView: - should return 1, since you've only got one column (component) to select from
  • -pickerView:didSelectRow:inComponent: - see below

You don't want the sound to start immediately when the row-selection delegate method gets called, or snippets of sounds will play continuously as the user scrolls the picker. Instead, use a timer with a short delay, something like this:

if(timer != nil)
{
    [timer invalidate]; // remove any timer from an earlier selection
    timer = nil;
}
timer = [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(startSoundAtURL:) userInfo:[[soundArr objectAtIndex:row] objectForKey:@"url"] repeats:NO]; // and create the new one

Then, implement a -startSoundAtURL: method that sets up the AVAudioPlayer to play that sound:

- (void)startSoundAtURL:(NSURL *)url
{
    if(audioPlayer != nil)
    {
        [audioPlayer stop];
        [audioPlayer release];
    }
    NSError *err;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
    if(err != nil)
    {
        NSLog([err description]);
        return;
    }
    [audioPlayer play];
}

That should pretty much do it.

Upvotes: 2

Related Questions