سؤال

هل هناك إشعار يمكنني الاستماع إليه يخبرني عند رفع مستوى صوت جهاز iPhone أعلى?

أنا أعرف عن AVSystemController_SystemVolumeDidChangeNotification, ، ولكن من الضروري ألا يتم تشغيل الإشعار إلا عند رفع مستوى الصوت، وليس لأعلى أو لأسفل.

ثانيا كيف يمكنني إخفاء المنظر الشفاف الذي يظهر عند الضغط على زر رفع الصوت ليظهر مستوى صوت النظام؟ الكاميرا+ وقد نفذت هذا.

هل كانت مفيدة؟

المحلول

لا توجد طريقة موثقة للقيام بذلك، ولكن يمكنك استخدام هذا الحل البديل.سجل ل AVSystemController_SystemVolumeDidChangeNotification إشعار وإضافة MPVolumeView مما سيمنع عرض حجم النظام من الظهور.

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, 0, 10, 0)];
[volumeView sizeToFit];
[self.view addSubview:volumeView];

ولا تنس أن تبدأ جلسة صوتية

AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);

في هذه الحالة، MPVolumeView مخفية عن المستخدم.

أما بالنسبة للتحقق مما إذا كان قد تم الضغط على مستوى الصوت لأعلى أو لأسفل، فما عليك سوى الضغط على مستوى صوت التطبيق الحالي

float volumeLevel = [[MPMusicPlayerController applicationMusicPlayer] volume];  

ومقارنتها بحجم الصوت الجديد بعد الضغط على الزر في رد اتصال الإشعارات

إذا كنت لا ترغب في القيام بذلك بنفسك، فهناك فصل دراسي متاح في جيثب

https://github.com/blladnar/RBVolumeButtons

نصائح أخرى

إذا كنت تريد حدثًا، يمكنك تسجيل المستمع على خاصية "outputVolume":

- (void)viewWillAppear:(BOOL)animated {

    AVAudioSession* audioSession = [AVAudioSession sharedInstance];

    [audioSession setActive:YES error:nil];
    [audioSession addObserver:self
                    forKeyPath:@"outputVolume"
                       options:0
                       context:nil];
}

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if ([keyPath isEqual:@"outputVolume"]) {
        NSLog(@"volume changed!");
    }
}

لقد قمت بحل هذه المشكلة عن طريق إضافة الهدف/الإجراء الخاص بـ UISlider الموجود بالداخل MPVolumeView.لذلك من الممكن التقاط أحداث تغيير مستوى الصوت وتحديد الزر الذي تم الضغط عليه.هنا جيثب الريبو مع تنفيذ هذا النهج.إنه يعمل بشكل جيد مع نظام التشغيل iOS 7 والإصدارات الأحدث، ولا توجد تحذيرات إهمال ولا يوجد رفض من شركة Apple.

من أجل التمييز بين حجم العمل: بدلاً من (في حارس مراقبة القيمة)

temp != 0.5

يستخدم لرفع مستوى الصوت فقط

temp > 0.5

واكتشف فقط خفض مستوى الصوت:

temp < 0.5 

سيتم طباعة هذا الحل أدناه في حالة الضغط على مستوى الصوت لأعلى أو لأسفل.

import AVFoundation
import MediaPlayer

override func viewDidLoad() {
  super.viewDidLoad()
  let volumeView = MPVolumeView(frame: CGRect.zero)
  for subview in volumeView.subviews {
    if let button = subview as? UIButton {
      button.setImage(nil, for: .normal)
      button.isEnabled = false
      button.sizeToFit()
    }
  }
  UIApplication.shared.windows.first?.addSubview(volumeView)
  UIApplication.shared.windows.first?.sendSubview(toBack: volumeView)
}

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  AVAudioSession.sharedInstance().addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
  do { try AVAudioSession.sharedInstance().setActive(true) }
  catch { debugPrint("\(error)") }   
}

override func viewDidDisappear(_ animated: Bool) {
  super.viewDidDisappear(animated)
  AVAudioSession.sharedInstance().removeObserver(self, forKeyPath: "outputVolume")
  do { try AVAudioSession.sharedInstance().setActive(false) } 
  catch { debugPrint("\(error)") }
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  guard let key = keyPath else { return }
  switch key {
    case "outputVolume":
      guard let dict = change, let temp = dict[NSKeyValueChangeKey.newKey] as? Float, temp != 0.5 else { return }
      let systemSlider = MPVolumeView().subviews.first { (aView) -> Bool in
        return NSStringFromClass(aView.classForCoder) == "MPVolumeSlider" ? true : false
      } as? UISlider
      systemSlider?.setValue(0.5, animated: false)
      guard systemSlider != nil else { return }
      debugPrint("Either volume button tapped.")
    default:
      break
  } 
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top