IOS 7: Недопустимый объем MPMusicPlayerController. Как изменить объем устройства сейчас?
MPMusicPlayerController setVolume устарел с iOS 7
Есть ли другой способ изменить громкость системной музыки? Предпочтительно без взаимодействия с пользователем.
Его важная функция: автоматически увеличить громкость для любого будильника из AppStore.
Ответы
Ответ 1
Чтобы ответить на вопрос точно:
Да, есть другой способ изменения объема системы без взаимодействия с пользователем.
До недавнего времени я привык думать, что изменение объема с использованием MPVolumeView программно возможно только при использовании private API. Но я только что подтвердил, что изменение значения функции volumeSlider и фальшивого слайдера touchUP:
MPVolumeView* volumeView = [[MPVolumeView alloc] init];
//find the volumeSlider
UISlider* volumeViewSlider = nil;
for (UIView *view in [volumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
break;
}
}
[volumeViewSlider setValue:1.0f animated:YES];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
(Когда слайдер получает событие touchUP, он сам вызовет метод _commitVolumeChange
, который изменит системный том)
Ответ 2
Пока Apple не сочтет нужным отменять это решение, есть два средства защиты, которые я обнаружил:
- Продолжайте использовать свойство volume, оно все еще работает в iOS 7.0.2
- Используйте AVAudioSession.outputVolume для чтения тома, когда ваше приложение просыпается и выдает предупреждение, содержащее MPVolumeView, если объем ниже (или выше) указанного пользователем значения. По крайней мере, ваш пользователь знает, что их тревога (или что-то еще) будет играть тихо и имеет возможность настроить громкость. В качестве альтернативы вы можете просто четко отобразить уровень громкости, чтобы они не получили никаких сюрпризов.
Ответ 3
Просто сделайте следующее:
let masterVolumeSlider: MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider{
view.value = 1.0
}
Ответ 4
@Hurden, я написал код Swift для реализации MPVolumeSlider:
for view in mpVolumeView.subviews {
let uiview: UIView = view as UIView
//println("\(uiview.description)")
if uiview.description.rangesOfString("MPVolumeSlider").first != nil {
mpVolumeSilder = (uiview as UISlider)
currentDeviceVolume = mpVolumeSilder!.value
return
}
}
Расширение func rangeOfString String можно найти здесь Swift: чистый метод Swift для возврата диапазонов экземпляра String (Xcode 6 Beta 5)
И используйте этот код, чтобы заставить жест и mpvolumeslider работать вместе
@IBAction func handlePan(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translationInView(self.view)
let dx = (translation.x-lastTranslationX)
let volumeChanged = Float(dx / mpVolumeView.frame.width)
currentDeviceVolume = currentDeviceVolume + Float(volumeChanged)
if currentDeviceVolume > 1 {
currentDeviceVolume = 1
} else if currentDeviceVolume < 0 {
currentDeviceVolume = 0
}
mpVolumeSilder!.value = currentDeviceVolume
if recognizer.state == .Changed {
lastTranslationX = translation.x
}
if recognizer.state == .Ended || recognizer.state == .Began {
lastTranslationX = 0
}
}
Ответ 5
Быстрая версия:
// Outlet added in Storyboard (Add UIView then set class to MPVolumeView)
@IBOutlet weak var mpVolumeView: MPVolumeView!
// Get volume slider within MPVolumeView
for subview in self.mpVolumeView.subviews {
if (subview as UIView).description.rangeOfString("MPVolumeSlider") != nil {
// Set volume
let volumeSlider = subview as UISlider
volumeSlider.value = 1
// Works with or without the following line:
// volumeSlider.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
break
}
}
Ответ 6
Это решение немного нервничает, и я думаю, что его немного странно, официальный API не существует, но вот мое решение Swift построено из сообщения lightlight.
var _volumeView = MPVolumeView()
var _volumeSlider : UISlider? = nil
self.view.addSubview(_volumeView)
_volumeView.hidden = true
var i = 0
while i < _volumeView.subviews.count {
if let _r = _volumeView.subviews[i] as? UISlider {
_volumeSlider = _r
break
}
++i
}
Ответ 7
let masterVolumeSlider : MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider{
view.value = fVolume!
view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
}
Ответ 8
По-видимому, есть способ изменить системный том , не отображая ничего вообще.
И лучше всего работает на iOS 11.
Вот как я это достиг:
1) Создайте две переменные в требуемом ViewController
let volumeView = MPVolumeView()
var slider: UISlider?
2) Добавьте код ниже в свой viewDidLoad
volumeView.alpha = 0.01
self.view.addSubview(volumeView)
if let view = volumeView.subviews.first as? UISlider {
slider = view
}
3) Измените выделение, когда вам нужно
slider?.value = 0.4