views:

270

answers:

2

I am trying to figure out how to hook up a button to play a sound programmatically without using IB. I have the code to play the sound, but have no way of hooking the button up to play the sound? any help?

here is my code that I'm using:

     - (void)playSound
    {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"boing_1" ofType:@"wav"];
        AVAudioPlayer* myAudio = [[AVAudioPlayer alloc] 
                 initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
        myAudio.delegate = self;
        myAudio.volume = 2.0;
        myAudio.numberOfLoops = 1;
        [myAudio play];
    }
A: 
[button addTarget:self action:@selector(playSound) forControlEvents:UIControlEventTouchUpInside];

UIButton inherits its target/action methods from UIControl.

macatomy
this is what i was looking for...i believe i've seen something like this before but couldn't remember where....this should work very well!
Brandon
A: 

To hook up the button, make your playSound method the handler for the button's UIControlEventTouchUpInside event. Assuming this is in a view controller, you might want to put this in the viewDidLoad method:

[button addTarget:self action:@selector(playSound) forControlEvents:UIControlEventTouchUpInside]; 

FYI, you're leaking memory because you're alloc-ing an object but never release-ing it.

You should create a new AVAudioPlayer member for the class to avoid this.

@interface MyViewController : ...
{
    ...
    AVAudioPlayer* myAudio;
    ...
}

- (void)playSound
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"boing_1" ofType:@"wav"];
    [myAudio release];
    myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
    myAudio.delegate = self;
    myAudio.volume = 2.0;
    myAudio.numberOfLoops = 1;
    [myAudio play];
}

Don't forget to put [myAudio release] in your dealloc method.

(I did this without declaring myAudio as a @property, but that's not strictly necessary)

Shaggy Frog
He probably shouldn't allocate a new instance of AVAudioPlayer every time the method is called. Do something like `if (!myAudio) { myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]]; }`
macatomy
Valid comment, although I think the idea should be "get it working" at first. :)
Shaggy Frog