George Armhold
George Armhold

Reputation: 31074

iPhone: how to make key click sound for custom keypad?

Is there a way to programmatically invoke the keypad "click" sound? My app has a custom keypad (built out of UIButtons) and I'd like to provide some audio feedback when the user taps on the keys. I tried creating my own sounds in Garageband, but wasn't happy with any of my creations. If there isn't a standard way to invoke the key click, can anyone point me to a library of sounds that might have such a gem?

Upvotes: 20

Views: 35153

Answers (10)

Ryan
Ryan

Reputation: 4855

As of iOS 4.2, adopt the UIInputViewAudioFeedback protocol on a custom subclass of UIView. Make this view your "inputView" and then call "playInputClick" at the appropriate time.

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIInputViewAudioFeedback_ProtocolReference/Reference/Reference.html

Just to save some people time. Put this in your custom view:

- (BOOL) enableInputClicksWhenVisible {
    return YES;
}

To make the click do this:

[[UIDevice currentDevice] playInputClick];

Upvotes: 22

bbeckford
bbeckford

Reputation: 4477

Here's what I did:

Locate 'Tock.aiff' in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/Frameworks/UIKit.framework

Drag it into your Resources folder in xCode, ticking 'Copy items into destination group's folder'

Import AVFoundation.framework into the Frameworks folder in xCode

Import AVFoundation at the top of your class:

#import <AVFoundation/AVAudioPlayer.h>

Use the following function:

- (void)PlayClick {
    NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] 
                                               pathForResource:@"Tock"
                                               ofType:@"aiff"]];
    AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
    [click setVolume:0.15f];
    [click play];
}

That's it!

Upvotes: 4

pposthoorn
pposthoorn

Reputation: 321

There is a really fast solution to play the default keyboard sound:

  1. Add AudioToolbox.framework

  2. Add the following line wherever you want the sound to play:

    AudioServicesPlaySystemSound(0x450);

Upvotes: 32

jyavenard
jyavenard

Reputation: 2095

You do not have to dispose of the sound object right away. Keep a pointer to that sound object in a property, and dispose of it only when you are about to play another sound before re-creating it.

And of course finally dispose of the SystemSoundID object in dealloc.

Upvotes: 1

jyavenard
jyavenard

Reputation: 2095

Maybe a bit late ... But in MrMage last post, if you do AudioServicesDisposeSystemSoundID(soundID); straight after AudioServicesPlaySystemSound(soundID); then you won't hear a thing as you're discarding the system sound right after creating it.

You have to let it finish playing first.. Only call AudioServicesDisposeSystemSoundID to cancel the sound before it finishes

Upvotes: 0

Sam McCall
Sam McCall

Reputation: 654

Using 0x450 as the SystemSoundID works for me (and at the correct volume - just playing the built-in Tock.aiff was too loud). No idea how portable that is - this is on an iPod Touch 3rd gen.

Still doesn't respect the preference for tick on/off.

Upvotes: 8

MrMage
MrMage

Reputation: 7487

This is what I made out of it aSquared's comment:

NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] pathForResource:@"Tock" ofType:@"aiff"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesDisposeSystemSoundID(soundID);

Upvotes: 8

aSquared
aSquared

Reputation: 131

No need to copy the file into your own app - you should be able to get it directly from the UIKit framework:

CFURLRef soundFileURLRef = CFBundleCopyResourceURL(
    CFBundleGetBundleWithIdentifier(CFSTR("com.apple.UIKit")),
    CFSTR ("Tock"),CFSTR ("aiff"),NULL);

Upvotes: 13

outis
outis

Reputation: 77400

From what I can tell, the click sound isn't available to apps. I haven't seen anything in audio session services that is relevant. AudioServicesPlaySystemSound() looks promising, but there doesn't appear to be any system sound ID for the click sound (a closer look at the headers may turn up something). You could always loop over a call to AudioServicesPlaySystemSound(i) and see if anything plays. The iPhone software restore images probably have the sound, but it's probably not licensed for general use. Jailbreaking an iPhone to get at the tasty click sound doesn't need to be mentioned.

For (creative commons) sounds, check out the Freesound Project.

For the future, perhaps request that Apple expose system sounds other than the alert sound for use with AudioServicesPlaySystemSound().

Upvotes: 2

Becca Royal-Gordon
Becca Royal-Gordon

Reputation: 17861

The simplest way I've found is to extract Tock.aiff (the keyboard sound) from the iPhone Simulator and package it with your app, then play it using AudioServicesPlaySystemSound() at the appropriate time. On my machine, simply typing Tock.aiff into Spotlight turns up the file, but if you have to go looking for it, it's in the simulator version of UIKit.framework.

Upvotes: 8

Related Questions