web-dev-qa-db-fra.com

Comment changer le volume par programme sur iOS 11.4

Auparavant, je définissais le volume sonore par programme en utilisant cette approche:

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];

Jusqu'au iOS 11.4, cela fonctionnait bien (même sur iOS 11.3), mais pas sur iOS 11.4. La valeur du volume reste inchangée. Quelqu'un peut aider avec ce problème? Merci.

8
Otto Boy

Changer volumeViewSlider.value après un petit délai résout le problème.

- (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;
  });
}

Version Swift

11
trungduc

Je l'ai résolu en ajoutant un nouveau MPVolumeView à ma vue UIViewController, sinon le volume n'était plus réglé. Lorsque je l'ai ajouté au contrôleur, je dois également définir la position de la vue du volume pour qu'elle soit en dehors de l'écran afin de le masquer à l'utilisateur. 

Je préfère ne pas utiliser le réglage du volume différé car cela complique les choses, surtout si vous devez jouer du son immédiatement après avoir réglé le volume.

Le code est dans 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)
}
2
Northern Captain

Je viens d'ajouter la MPVolumeView en tant que sous-vue à une autre vue (qui n'a jamais été dessinée à l'écran).

Cela devait être fait avant toute tentative de réglage ou d’obtention du volume.

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

func prepareWorkaround() {
    self.containerView.addSubview(self.volumeView)
}
1
Ric Santos

Je devais avoir un MPVolumeView en tant que sous-vue à une vue dans la hiérarchie pour que le hud ne s'affiche pas sur iOS 12. Il doit être légèrement visible: 

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

Lorsque je règle le volume, le curseur de MPVolumeView est identique à celui des affiches précédentes et je règle la valeur:

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

    slider.value = volumeLevel
}
0
jalmaas