【问题标题】:How to turn off Background Music using a Toggle Switch in Xcode using Swift?如何使用 Swift 在 Xcode 中使用切换开关关闭背景音乐?
【发布时间】:2020-11-10 20:28:18
【问题描述】:

应用启动后,我正在通过应用委托在我的应用中播放背景音乐。现在,在我的第二个 V.C.我设置了一个拨动开关来关闭/关闭背景音乐。但是,每当我运行以下代码时,我的应用程序都会崩溃并给我这个错误:-

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

谁能告诉我如何在我的 V.C. 中实现以下任务。感谢您的帮助!谢谢:)

**App Delegate**

let vc = SecondViewController()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    
    vc.playMusic()
    
    return true
}

**Second View Controller**

import UIKit
import AVFoundation

class SecondViewController: UIViewController {

@IBOutlet weak var musicToggleSwitch: UISwitch!

var music: AVAudioPlayer!

let vc_1 = ViewController()

override func viewDidLoad() {
    super.viewDidLoad()
  
    self.musicToggleSwitch.setOn(UserDefaults.standard.bool(forKey: "musicToggleState"), animated: true)
    
   }

@IBAction func musicToggleSwitch(_ sender: UISwitch) {
    
    if (musicToggleSwitch.isOn == true) {
        
        if (music.isPlaying == false) {
            
            music.play()
            
        }
        
    }
    else {
        
        if (music.isPlaying == true) {
            
            music.stop()
            
        }
        
    }
    
    UserDefaults.standard.set(sender.isOn, forKey: "musicToggleState")

}

func playMusic() {
    
    if let musicURL = Bundle.main.url(forResource: "Music", withExtension: "mp3") {
        if let audioPlayer = try? AVAudioPlayer(contentsOf: musicURL) {
            music = audioPlayer
            music.numberOfLoops = -1
            music.play()
        }
    }
    
}

}

【问题讨论】:

  • 能不能写个NSLog来看看nil值是从哪里得到的?
  • @zeytin 感谢您的回复!我在这一行遇到错误:if (music.isPlaying == true) {
  • var 音乐:AVAudioPlayer?你能像这样可选吗?
  • @zeytin 我试过了,但现在应用程序没有崩溃,但是我切换开关后音乐仍然没有停止
  • 你能检查一下musicURL是否有效吗?我假设在playMusic() 中创建音乐播放器失败,当您切换开关时,它会尝试访问music,这是 nil

标签: ios swift


【解决方案1】:

这应该可以解决您的问题。

如果还是不播放,在music变量的创建块中加一些断点看看哪里出错了。

class SecondViewController: UIViewController {
    
    @IBOutlet weak var musicToggleSwitch: UISwitch!
    
    var music: AVAudioPlayer? = {
        guard let musicURL = Bundle.main.url(forResource: "Music", withExtension: "mp3") else {
            return nil
        }
        
        let audioPlayer = try? AVAudioPlayer(contentsOf: musicURL)
        audioPlayer?.numberOfLoops = -1
        return audioPlayer
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.musicToggleSwitch.setOn(UserDefaults.standard.bool(forKey: "musicToggleState"), animated: true)
    }
    
    @IBAction func musicToggleSwitch(_ sender: UISwitch) {
        guard let music = music, sender.isOn != music.isPlaying else {
            return
        }
        
        if sender.isOn {
            music.play()
        } else {
            music.stop()
        }
        
        UserDefaults.standard.set(sender.isOn, forKey: "musicToggleState")
    }
    
    func playMusic() {
        music?.play()
    }
}

【讨论】:

    【解决方案2】:

    问题出在这一行:

    let vc = SecondViewController()
    

    这与您在界面中看到的 SecondViewController 不同。所以playMusic在错误的视图控制器上被调用,在视图控制器上你可以看到music仍然是nil然后你崩溃了。

    【讨论】:

    • 确实,因为您在应用程序委托中保持第二个 SecondViewController 活着,不可见。但这不是您看到并点击其按钮的 SecondViewController,而是崩溃的地方。必须理解类和实例之间的区别,这是面向对象编程的基础。您有两个 SecondViewController 实例和两个 music 播放器,其中一个是 nil,因为它的 playMusic 从未被调用过。世界上所有的反对票都不会伪造我的话,这是简单的事实。
    猜你喜欢
    • 2011-05-30
    • 2011-04-07
    • 2023-03-09
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多