Configure TableViewCell to play audio - uitableview

I have an app that currently plays a 5 sec sound when a button is pressed within a view controller. I am trying to change this set up to where if I have a tableview, a specific cell is touched and the sound plays. I do not want an action where you select the cell and it pushes to another window to play the sound. I simply want the sound to play on touch of the cell.
Currently for my button set up I had the following to play the sound in my view controller:
In the SoundLibViewController.h
// Identifying UIButton associated with sound file
-(IBAction)CarHorn:(id)sender;
#end
In the SoundLibViewController.m
-(IBAction)CarHorn:(id)sender {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"CarHorn", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
Unfortunately I can not find any help online to point me in the direction to change my code into incorporate a tableviewcell.
To give an example of what I'm looking to do: You go into your iPhone/iPad and under settings you select "Sounds". Then you choose "Ringtone", which takes you to a list of sounds. If you press the cell related to the sound it plays. THAT is what I want to do.

You need something like this in your UITableViewDelegate
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * soundName = [self.soundNames objectAtIndex: indexPath.row]; // Assuming you have an array of sound names
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef)soundName, CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}

Related

Music Not Playing - XCode

I have this code to play sounds:
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"audio2", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
It works fine for an audio file that I have that is about 1 second long. It does not, however, work for one of my files that is about 4 minutes long. How can I fix this? They're both mp3 files and placed in the same directory.
According to the apple's doc, AudioServicesPlaySystemSound has a limits as below:
Sound files that you play using this function must be:
- No longer than 30 seconds in duration
You can use AVAudioPlayer instead.

Sound not playing when iPhone is in silent mode

I am making an app that needs to play sounds even if the iPhone is in silent mode, but with the code I have now (look at bottom of this post) it wont't play sounds if the iPhone is in silent mode.
I am using the following code:
Viewcontroller.h:
#interface SoundViewController : UIViewController <UICollectionViewDataSource, UIApplicationDelegate, AVAudioPlayerDelegate, ADBannerViewDelegate, UIActionSheetDelegate> {
SystemSoundID SoundID;
NSString *listPath;
}
ViewController.m:
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (__bridge CFStringRef) [mainArray objectAtIndex:indexPath.row], CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
The way you are triggering sounds using AudioServicesPlaySystemSound will ALWAYS obey the ringer/silent switch.
To play sound when the device is set to silent you need to use another way such as AVAudioPlayer class.

1 button, plays 10 sounds?

1 button, plays 10 sounds?
How can I get a button to play some sounds in on order?
How can I add an extra sound to this action?
-(IBAction)sound1
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"sound1", CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
I've had the best luck with AVAudioPlayer - it's a library called AVFoundation you can import through "Build Phases" (first click on the blue xcode project name at top left) and then "Link Binary with Libraries"
Then try this really simple YouTube tutorial to make a button play sound:
http://youtu.be/kCpw6iP90cY
That's the same video I used 2 years ago to create my first sound board. Xcode 5 is a little different but the code will all work.
Ok now you need to create an array of these sounds that will cycle through them. Check out this link from TreeHouse:
https://teamtreehouse.com/forum/creating-an-array-with-mp3-sound-files
If the sounds are name sound0 … soundN, you can just introduce to ivars — one tracks the current index, one defines the number of sounds.
#implementation MyClass {
NSUInteger soundIdx;
NSUInteger soundCount;
}
-(instancetype) init //or any other entry point method like viewDidLoad,....
{
self = [super init];
if (self) {
soundCount = 10;
}
return self;
}
-(IBAction)sound
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) [NSString stringWithFormat:#"sound%lu", soundIdx], CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
soundIdx = (++soundIdx) % soundCount;
}
#end
If the sound names do not follow any particular naming convention, you could put them in an array
#implementation MyClass {
NSUInteger soundIdx;
NSArray *soundNames;
}
-(instancetype) init //or any other entry point method like viewDidLoad,....
{
self = [super init];
if (self) {
soundNames = #[#"sound1",#"hello", #"ping"];
}
return self;
}
-(IBAction)sound
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) soundNames[soundIdx], CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
soundIdx = (++soundIdx) % [soundNames count];
}
#end

Button not playing audio in iOS

I uploaded a file audio.wav into my supporting files folder.
This is my PlayAudio.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#interface PlayAudio : UIViewController {
}
-(IBAction) PlayIt;
#end
This is my PlayAudio.m after the implementation command
- (IBAction) PlayIt; {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"audio", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
I then ctrl-clicked from the play button to the First Responder in my view controller and selected PlayIt. I see it's associated with Touch Up Inside.
For some reason I can click the button, but nothing plays. I'm doing this in Storyboard.
You can use NSURL to get the path of your wav file and cast it to CFURLRef, check the following code:
SystemSoundID soundID;
NSURL *soundPath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"audio" ofType:#"wav"]];
if (AudioServicesCreateSystemSoundID ((CFURLRef)soundPath, &soundID) != kAudioServicesNoError) {
AudioServicesPlayAlertSound(soundID);
}
Note, that if mute button on iphone is enable AudioServicesCreateSystemSoundID function will fail(Vibration can be used in this case:soundID = kSystemSoundID_Vibrate;). If you want to play sound disregarding the mute switch, use AVAudioPlayer api.

iOS UITextField keep keyboard on the screen

I don't have the "[sender resignFirstResponder]" method called, but my keyboard still closes when the done button is pressed. I need it to stay open, even when I click done. How can I go about doing this?
Here's my action that controls the keyboard:
- (IBAction)returnKeyButton:(id)sender {
BOOL guessCorrect = [gameModel checkGuess:guessTextField.text];
guessTextField.text = #"";
if (guessCorrect) {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"rightAnswer", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
if (gameModel.score == 10) {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"win", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
[self endGameWithMessage:#"You win!"];
} else {
scrambledWord.text = [gameModel getScrambledWord];
}
}
remainingTime.text = [NSString stringWithFormat:#"%i", gameModel.time];
playerScore.text = [NSString stringWithFormat:#"%i", gameModel.score];
}
First of... to be honest, I have never had the problem you have. I always had to use the resign call to close the keyboard or it would stay open... But, this is what I used for you:
1) Put this in the .h file:
-(IBAction) textFieldDoneEditing : (id) sender;
2) Put this in the .m file:
-(IBAction) textFieldDoneEditing : (id) sender{
[sender resignFirstResponder];
[sender becomeFirstResponder];
}
3) Right click the UITextField in the storyboard and set the Sent Event "Editing Did End" to the textFieldDoneEditing method in the view controller.
Now, whenever the user presses "Return" or "Done", the keyboard will open and close instantaneously. Hope it helps! :)
If it doesn't work, look at my Xcode Project (which does work)... download it here

Resources