ios objective-c ios9 mpmusicplayercontroller mpvolumeview

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í:

  1. Defina un MPVolumeView y un UISlider opcional en su controlador de vista

    private let volumeView: MPVolumeView = MPVolumeView() private var volumeSlider: UISlider?

  2. 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!

  3. 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 } } }

  4. 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)