【问题标题】:iPhone: how to make key click sound for custom keypad?iPhone:如何为自定义键盘制作按键声音?
【发布时间】:2024-04-19 10:50:01
【问题描述】:

有没有办法以编程方式调用键盘“点击”声音?我的应用程序有一个自定义键盘(由 UIButtons 构建),我想在用户点击按键时提供一些音频反馈。我尝试在 Garageband 中创建自己的声音,但对我的任何创作都不满意。如果没有调用按键的标准方法,谁能给我指出一个可能有这样一个宝石的声音库?

【问题讨论】:

    标签: iphone audio click


    【解决方案1】:

    播放默认键盘声音有一个非常快速的解决方案:

    1. 添加 AudioToolbox.framework

    2. 在您希望播放声音的任何位置添加以下行:

      AudioServicesPlaySystemSound(0x450);

    【讨论】:

    • 这是在工具箱中播放任何声音的好方法。
    • 在 iOS 7 上似乎对我不起作用。不确定 id 是否已更改或是否是其他问题。
    • ID 已更改。试试 AudioServicesPlaySystemSound(1104);.
    • 仅供参考:0x450(十六进制)是 1104(十进制);相同的 ID。
    【解决方案2】:

    从 iOS 4.2 开始,在 UIView 的自定义子类上采用 UIInputViewAudioFeedback 协议。将此视图设为您的“inputView”,然后在适当的时候调用“playInputClick”。

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

    只是为了节省一些人的时间。把它放在你的自定义视图中:

    - (BOOL) enableInputClicksWhenVisible {
        return YES;
    }
    

    要让点击这样做:

    [[UIDevice currentDevice] playInputClick];
    

    【讨论】:

    • 这似乎是正确的做法,因为它将尊重用户对键盘点击声音的全局设置。但这似乎不起作用。有人成功实现过这个方法吗?
    • 这对我来说非常好用,但是它有一个问题,它只有在键盘可见时才有效......它非常适合用于文本视图和文本字段的辅助视图和备用输入视图,但如果您只想随时随地播放声音,这不是一个解决方案。
    • 太棒了!对于键盘上的附件视图,这是正确的方法。我以前从未见过这个。
    • 在此处查看此示例实现:*.com/a/39385287/1306012
    【解决方案3】:

    无需将文件复制到您自己的应用程序中 - 您应该可以直接从 UIKit 框架中获取它:

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

    【讨论】:

    • 如何将其放入代码中?我尝试了 AudioServicesCreateSystemSoundID(soundFileURLRef) 但它抛出了一个错误......
    【解决方案4】:

    这是我根据 aSquared 的评论做出的:

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

    【讨论】:

    • iOS 7 不再捆绑 Tock.aiff。
    【解决方案5】:

    我找到的最简单的方法是从 iPhone 模拟器中提取 Tock.aiff(键盘声音)并将其与您的应用程序打包,然后在适当的时候使用 AudioServicesPlaySystemSound() 播放它。在我的机器上,只需在 Spotlight 中键入 Tock.aiff 即可打开该文件,但如果您必须去寻找它,它位于 UIKit.framework 的模拟器版本中。

    【讨论】:

    • 我实际上已经使用节拍器示例中的“Tock.caf”进行了测试,但由于担心版权问题而不愿将其包含在成品中。这是“允许的”吗?
    • 根据我对 iPhone 开发者许可协议的阅读(免责声明:我不是律师),您不能使用 Tock.aiff,除非您可以找到它作为示例代码的一部分或开源组件(第 2.6 节)。
    • 目前尚不清楚这在技术上是否合法,但我现在已经在两个应用程序中完成了,并且没有收到任何投诉。也许苹果实际上愿意一次就某件事讲道理。如果没有,可能有一种方法可以使用 iPhone 上已有的副本,但如果 Apple 删除声音,这似乎很容易被破坏。
    • 它绝对可以在示例代码中找到——查看节拍器示例。它包括“tick”和“tock”声音文件,但我不确定这些声音是否与“系统”实际使用的声音相同。
    • 请记住,这将忽略用户禁用键盘声音的偏好。
    【解决方案6】:

    使用 0x450 作为 SystemSoundID 对我有用(并且音量正确 - 只是播放内置的 Tock.aiff 声音太大了)。不知道它的便携性——这是在第三代 iPod Touch 上。

    仍然不尊重勾选/关闭的偏好。

    【讨论】:

    • 谢谢你,这很完美。请将相同的答案发布到*.com/questions/1513986/…,这样我就可以给你赏金(你最应得的)。
    【解决方案7】:

    这就是我所做的:

    在以下位置找到“Tock.aiff”:/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/Frameworks/UIKit.framework

    将它拖到 xCode 中的资源文件夹中,勾选“将项目复制到目标组的文件夹”

    将 AVFoundation.framework 导入 xCode 的 Frameworks 文件夹中

    在班级顶部导入 AVFoundation:

    #import <AVFoundation/AVAudioPlayer.h>
    

    使用以下函数:

    - (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];
    }
    

    就是这样!

    【讨论】:

      【解决方案8】:

      据我所知,点击声音不适用于应用程序。我在音频会话服务中没有看到任何相关的内容。 AudioServicesPlaySystemSound() 看起来很有希望,但似乎没有任何系统声音 ID 用于点击声音(仔细查看标题可能会出现一些东西)。您可以随时循环调用AudioServicesPlaySystemSound(i) 并查看是否有任何播放。 iPhone 软件恢复图像可能有声音,但它可能未获得一般使用许可。无需提及越狱 iPhone 以获得美妙的咔哒声。

      对于(知识共享)声音,请查看Freesound Project

      对于未来,也许要求 Apple 公开除警报声音之外的系统声音,以便与 AudioServicesPlaySystemSound() 一起使用。

      【讨论】:

        【解决方案9】:

        可能有点晚了... 但是在 MrMage 上一篇文章中,如果你在 AudioServicesPlaySystemSound(soundID); 之后直接做 AudioServicesDisposeSystemSoundID(soundID); 那么您将听不到任何声音,因为您在创建系统声音后立即丢弃它。

        你必须先让它完成播放。只有在它完成之前调用 AudioServicesDisposeSystemSoundID 来取消声音

        【讨论】:

        • 播放系统声音确实让我的界面动画变慢了。有更快的方法吗?
        • 您可以改为在第二个线程中播放声音。使用 NSOperationQueue 在第二个线程中启动任务。而是在那里开始声音
        【解决方案10】:

        您不必立即处理声音对象。 将指向该声音对象的指针保存在属性中,并仅在您要播放另一个声音时才释放它,然后再重新创建它。

        当然最后在 dealloc 中处理 SystemSoundID 对象。

        【讨论】: