Swift编程实现音量HUD的显示与隐藏(无需访问视图)
如何在Swift中便捷控制系统音量HUD的显示与隐藏
嘿,我来帮你搞定这个问题!不用折腾视图层级里的添加/移除子视图操作,我们可以直接通过系统API或者小技巧来优雅控制音量HUD的显示和隐藏,下面给你分情况讲解靠谱的方案:
一、主动隐藏已显示的音量HUD
如果你想立刻让正在显示的音量HUD消失,有两种方式可选:
方案1:直接调用系统私有API(高效但有审核风险)
这种方式不需要碰任何视图,直接通过系统内部的AVSystemController来控制HUD的可见性,代码非常简洁:
import AVFoundation func hideVolumeHUD() { guard let avSystemController = NSClassFromString("AVSystemController") as? NSObjectProtocol else { return } let hideSelector = Selector(("setVolumeHUDVisible:forAudioCategory:")) guard avSystemController.responds(to: hideSelector) else { return } // 传入false隐藏HUD,同时传入当前音频分类 avSystemController.perform(hideSelector, with: false, with: AVAudioSession.sharedInstance().category.rawValue) }
注意:这个方案用到了苹果的私有API,提交App Store审核时大概率会被拒绝,适合内部测试应用或企业级应用使用。
方案2:合法的间接隐藏技巧(无审核风险)
系统音量HUD默认会在显示后几秒自动消失,如果你不想等,也可以通过快速调整音量再恢复的方式让HUD提前消失(因为系统会认为音量调整已完成,自动收起HUD):
import AVFoundation func hideVolumeHUDSafely() { let volumeView = MPVolumeView() guard let volumeSlider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider else { return } let originalVolume = volumeSlider.value // 微小调整音量触发HUD收起逻辑 volumeSlider.value = max(originalVolume - 0.01, 0.0) DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { volumeSlider.value = originalVolume } }
这个方案完全使用公开API,不会有审核风险,只是会有极其微小的音量波动(几乎听不到)。
二、主动重新显示音量HUD
如果需要主动触发音量HUD显示,同样有两种方案:
方案1:私有API直接触发(高效)
和隐藏逻辑类似,直接调用AVSystemController的方法设置HUD可见:
import AVFoundation func showVolumeHUD() { guard let avSystemController = NSClassFromString("AVSystemController") as? NSObjectProtocol else { return } let showSelector = Selector(("setVolumeHUDVisible:forAudioCategory:")) guard avSystemController.responds(to: showSelector) else { return } // 传入true显示HUD avSystemController.perform(showSelector, with: true, with: AVAudioSession.sharedInstance().category.rawValue) }
同样需要注意私有API的审核风险。
方案2:合法的音量调整触发(无风险)
通过微小调整系统音量来触发HUD显示,之后再恢复原音量,全程用公开API:
import AVFoundation func showVolumeHUDSafely() { let volumeView = MPVolumeView() guard let volumeSlider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider else { return } let originalVolume = volumeSlider.value // 微小调整音量触发HUD显示 volumeSlider.value = min(originalVolume + 0.01, 1.0) DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { volumeSlider.value = originalVolume } }
这个方案完全合规,只是会有几乎不可察觉的音量变化。
内容的提问来源于stack exchange,提问作者user9464377
相关产品推荐
相关产品推荐

