###前提・実現したいこと
・機種はipad(iphoneでは発生しない)
・viewDidLoad()内で、フォアグランド、バックグラウンド、音量変更の通知を登録する。
・バックグラウンド移行で音量変更通知を解除する。
・バックグラウンド時に、音量変更ボタンで音量を変更する。
・フォアグラウンド移行で音量変更通知を登録する。
###発生している問題・エラーメッセージ
エラーメッセージ ・下記ソースコードにおいて、フォアグランド移行のタイミングで "volumeChange"がバックグラウンドで音量を変更した回数だけ表示される。
###該当のソースコード
import UIKit import MediaPlayer class XXX { private var slider = UISlider() override func viewDidLoad() { super.viewDidLoad() let volumeView = MPVolumeView(frame : CGRect(x : 100, y : 100, width : 500, height : 10)) view.addSubview(volumeView) for view in volumeView.subviews { if (view.isKind(of: UISlider.self)) { // 音量変更をスライダーと結びつける self.slider = view as! UISlider break } } // フォアグラウンド NotificationCenter.default.addObserver(self, selector: #selector(XXX.enterForeground(_:)), name: .UIApplicationWillEnterForeground, object: nil) // バックグラウンド NotificationCenter.default.addObserver(self, selector: #selector(XXX.enterBackground(_:)), name: .UIApplicationDidEnterBackground, object: nil) // 音量変更 NotificationCenter.default.addObserver(self, selector: #selector(XXX.volumeChange(_:)), name: NSNotification.Name("AVSystemController_SystemVolumeDidChangeNotification"), object: nil) } // フォアグラウンド通知 @objc func enterForeground(_ notification : Notification?) { if (self.isViewLoaded && (self.view.window != nil)) { // 登録 NotificationCenter.default.addObserver(self, selector: #selector(XXX.volumeChange(_:)), name: NSNotification.Name("AVSystemController_SystemVolumeDidChangeNotification"), object: nil) } } // バックグラウンド通知 @objc func enterBackground(_ notification : Notification?) { if (self.isViewLoaded && (self.view.window != nil)) { // 解除 NotificationCenter.default.removeObserver(self, name: NSNotification.Name("AVSystemController_SystemVolumeDidChangeNotification"), object: nil) } } // 音量変更 @objc private func volumeChange(_ notification: Notification?) { print("volumeChange") }
###試したこと・質問
・色々試したところ、DispatchQueue.main.asyncAfterで遅延実行時に登録すると、"volumeChange"は表示されません。
以下参照。
// フォアグラウンド通知 @objc func enterForeground(_ notification : Notification?) { if (self.isViewLoaded && (self.view.window != nil)) { // 遅延実行する必要あり? DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // 登録 NotificationCenter.default.addObserver(self, selector: #selector(XXX.volumeChange(_:)), name: NSNotification.Name("AVSystemController_SystemVolumeDidChangeNotification"), object: nil) } } }
質問1. これは正しい処置なのでしょうか?
質問2. 何故、この処置で上手くいくのでしょうか?
質問3. 正しい処置を教えていただけないでしょうか?
以上、宜しくお願いします。
回答1件
あなたの回答
tips
プレビュー