iOS 9: ¿Cómo cambiar el volumen mediante programación sin mostrar la ventana emergente de la barra de sonido del sistema?
objective-c ios9 (10)
Para 2018, trabajando en iOS 11.4
slider.value
cambiar el valor de
slider.value
después de un pequeño retraso.
extension MPVolumeView {
static func setVolume(_ volume: Float) {
let volumeView = MPVolumeView()
let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
slider?.value = volume
}
}
}
Uso:
MPVolumeView.setVolume(0.5)
Versión Objective-C
Tengo que cambiar el volumen en iPad y usar este código:
[[MPMusicPlayerController applicationMusicPlayer] setVolume:0];
Pero este volumen cambiante y muestra la barra de volumen del sistema en iPad. ¿Cómo cambiar el sonido sin mostrar la barra de volumen?
Lo sé,
setVolume:
está en desuso, y todo el mundo dice que use
MPVolumeView
.
Si esta es la única forma de resolver mi problema, ¿cómo cambiar el volumen con
MPVolumeView
?
No veo ningún método en
MPVolumeView
que cambie el sonido.
¿Debo usar alguna otra clase junto con
MPVolumeView
?
Pero es preferible usar
MPMusicPlayerController
.
¡Gracias por tu consejo!
Aquí hay una solución en Swift. Puede ser sombrío, por lo que le haré saber si Apple aprobó esto cuando publique. Mientras tanto, esto funciona bien para mí:
-
Defina un MPVolumeView y un UISlider opcional en su controlador de vista
private let volumeView: MPVolumeView = MPVolumeView() private var volumeSlider: UISlider?
-
En el guión gráfico, defina una vista que esté oculta para el usuario (height = 0 debería ser el truco) y configure una salida para ello (lo llamaremos hiddenView aquí). Este paso solo es bueno si no desea mostrar el volumen del HUD al cambiar el volumen (vea la nota a continuación):
@IBOutlet weak var hiddenView: UIView!
-
En viewDidLoad () o en algún lugar init-y que se ejecute una vez, capture el UISlider que realmente controla el volumen en el UISlider opcional desde el paso (1):
override func viewDidLoad() { super.viewDidLoad() ... hiddenView.addSubview(volumeView) for view in volumeView.subviews { if let vs = view as? UISlider { volumeSlider = vs break } } }
-
Cuando desee configurar el volumen en su código, simplemente configure volumeSlider? .Value para que esté entre 0.0 y 1.0, por ejemplo, para aumentar el volumen:
func someFunc() { if volumeSlider?.value < 0.99 { volumeSlider?.value += 0.01 } else { volumeSlider?.value = 1.0 } }
Nota importante: esta solución evitará que aparezca el HUD de volumen del iPhone, ya sea cuando cambie el volumen en su código o cuando el usuario haga clic en los botones de volumen externo. Si desea mostrar el HUD, omita todas las vistas ocultas y no agregue MPVolumeView como una subvista. Esto hará que iOS muestre el HUD cuando cambie el volumen.
La respuesta de @udjat en Swift 3
extension MPVolumeView {
var volumeSlider: UISlider? {
showsRouteButton = false
showsVolumeSlider = false
isHidden = true
for subview in subviews where subview is UISlider {
let slider = subview as! UISlider
slider.isContinuous = false
slider.value = AVAudioSession.sharedInstance().outputVolume
return slider
}
return nil
}
}
No creo que haya ninguna forma de cambiar el volumen sin parpadear el control de volumen.
Deberías usar
MPVolumeView
así:
MPVolumeView* volumeView = [[MPVolumeView alloc] init];
// Get the Volume Slider
UISlider* volumeViewSlider = nil;
for (UIView *view in [volumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
break;
}
}
// Fake the volume setting
[volumeViewSlider setValue:1.0f animated:YES];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
Puede usar UISlider predeterminado con este código:
import MediaPlayer
class CusomViewCOntroller: UIViewController
// could be IBOutlet
var customSlider = UISlider()
// in code
var systemSlider = UISlider()
override func viewDidLoad() {
super.viewDidLoad()
let volumeView = MPVolumeView()
if let view = volumeView.subviews.first as? UISlider{
systemSlider = view
}
}
siguiente en el código solo escribe
systemSlider.value = customSlide.value
Swift> 2.2, iOS> 8.0,
No encontré ninguna solución que estaba buscando, pero termino haciendo esto como solución:
let volumeView = MPVolumeView()
override func viewDidLoad() {
...
view.addSubview(volumeView)
volumeView.alpha = 0.00001
}
func changeSpeakerSliderPanelControls(volume: Float) {
for subview in self.volumeView.subviews {
if subview.description.rangeOfString("MPVolumeSlider") != nil {
let slider = subview as! UISlider
slider.value = volume
break
}
}
}
MPVolumeView
tiene un control deslizante y, al cambiar el valor del control deslizante, puede cambiar el volumen del dispositivo.
Escribí una extensión
MPVolumeView
para acceder fácilmente al control deslizante:
extension MPVolumeView {
var volumeSlider:UISlider {
self.showsRouteButton = false
self.showsVolumeSlider = false
self.hidden = true
var slider = UISlider()
for subview in self.subviews {
if subview.isKindOfClass(UISlider){
slider = subview as! UISlider
slider.continuous = false
(subview as! UISlider).value = AVAudioSession.sharedInstance().outputVolume
return slider
}
}
return slider
}
}
Swift 4:
var player: AVPlayer!
...
player.volume = 0.5 // 50% level
Versión: Swift 3 y Xcode 8.1
extension MPVolumeView {
var volumeSlider:UISlider { // hacking for changing volume by programing
var slider = UISlider()
for subview in self.subviews {
if subview is UISlider {
slider = subview as! UISlider
slider.isContinuous = false
(subview as! UISlider).value = AVAudioSession.sharedInstance().outputVolume
return slider
}
}
return slider
}
}
extension UIViewController {
func setVolumeStealthily(_ volume: Float) {
guard let view = viewIfLoaded else {
assertionFailure("The view must be loaded to set the volume with no UI")
return
}
let volumeView = MPVolumeView(frame: .zero)
guard let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider else {
assertionFailure("Unable to find the slider")
return
}
volumeView.clipsToBounds = true
view.addSubview(volumeView)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak slider, weak volumeView] in
slider?.setValue(volume, animated: false)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak volumeView] in
volumeView?.removeFromSuperview()
}
}
}
}
Uso:
// set volume to 50%
viewController.setVolume(0.5)