Подтвердить что ты не робот

IOS 7: Недопустимый объем MPMusicPlayerController. Как изменить объем устройства сейчас?

MPMusicPlayerController setVolume устарел с iOS 7

Есть ли другой способ изменить громкость системной музыки? Предпочтительно без взаимодействия с пользователем. Его важная функция: автоматически увеличить громкость для любого будильника из AppStore.

4b9b3361

Ответ 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