Как программно изменить громкость на iOS 11.4

Раньше я устанавливал громкость звука программно, используя такой подход:

MPVolumeView *volumeView = [[MPVolumeView alloc] init];
UISlider *volumeViewSlider = nil;

for (UIView *view in [volumeView subviews])
{
    if ([view.class.description isEqualToString:@"MPVolumeSlider"])
    {
        volumeViewSlider = (UISlider *)view;
        break;
    }
}

[volumeViewSlider setValue:0.5 animated:YES];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

До iOS 11.4 он работал хорошо (даже на iOS 11.3), а на iOS 11.4 — нет. Значение объема остается неизменным. Может ли кто-нибудь помочь с этой проблемой? Спасибо.


person iOS Dev    schedule 07.06.2018    source источник
comment
Почему вы хотите уменьшить громкость программно? Ваше приложение само генерирует звук? Вы не захотите увеличивать громкость до максимума без согласия пользователя, и в равной степени уменьшение громкости других приложений без контроля пользователя также нежелательно. Если ваше приложение само издает звук, который необходимо усилить или ослабить, добавьте узел усиления в свою аудиоцепочку.   -  person Toine Heuvelmans    schedule 07.06.2018


Ответы (4)


Изменение volumeViewSlider.value после небольшой задержки решает проблему.

- (IBAction)increase:(id)sender {
  MPVolumeView *volumeView = [[MPVolumeView alloc] init];
  UISlider *volumeViewSlider = nil;

  for (UIView *view in volumeView.subviews) {
    if ([view isKindOfClass:[UISlider class]]) {
      volumeViewSlider = (UISlider *)view;
      break;
    }
  }

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    volumeViewSlider.value = 0.5f;
  });
}

Версия Swift

person trungduc    schedule 07.06.2018
comment
iOS12.3.1 не работает, аналогичная ситуация? - person Bingerz; 10.06.2019
comment
Вместо задержки громкость можно установить в viewDidAppear. Поработай хоть у меня. - person gavv; 23.06.2020

Я решил это, добавив новый MPVolumeView в мое представление UIViewController, иначе он больше не устанавливал громкость. Поскольку я добавил его в контроллер, мне также нужно установить положение просмотра объема за пределами экрана, чтобы скрыть его от пользователя.

Я предпочитаю не использовать настройку громкости с задержкой, так как это усложняет задачу, особенно если вам нужно воспроизвести звук сразу после настройки громкости.

Код находится в Swift 4:

let volumeControl = MPVolumeView(frame: CGRect(x: 0, y: 0, width: 120, height: 120))

override func viewDidLoad() {
   self.view.addSubview(volumeControl);
}

override func viewDidLayoutSubviews() {
   volumeControl.frame = CGRect(x: -120, y: -120, width: 100, height: 100);
}

func setVolume(_ volume: Float) {
    let lst = volumeControl.subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}
    let slider = lst.first as? UISlider

    slider?.setValue(volume, animated: false)
}
person Northern Captain    schedule 08.06.2018

Я просто добавил MPVolumeView в качестве подпредставления к другому представлению (которое никогда не отображалось на экране).

Это должно было быть сделано до любой попытки установить или получить громкость.

private let containerView = UIView()
private let volumeView = MPVolumeView()

func prepareWorkaround() {
    self.containerView.addSubview(self.volumeView)
}
person Ric Santos    schedule 15.07.2018

Мне нужно было иметь MPVolumeView в качестве подпредставления для представления в иерархии, чтобы hud не отображался в iOS 12. Он должен быть немного виден:

let volume = MPVolumeView(frame: .zero)
volume.setVolumeThumbImage(UIImage(), for: UIControl.State())
volume.isUserInteractionEnabled = false
volumelume.alpha = 0.0001
volume.showsRouteButton = false
view.addSubview(volume)

При настройке громкости я получаю ползунок из MPVolumeView, как и в предыдущих постах, и устанавливаю значение:

func setVolumeLevel(_ volumeLevel: Float) {
    guard let slider = volume.subviews.compactMap({ $0 as? UISlider }).first else {
        return
    }

    slider.value = volumeLevel
}
person jalmaas    schedule 13.02.2019