初始化 AVAudioPlayer 以用于多个函数
Initializing AVAudioPlayer to be used in more than one function
通常的 AVAudioPlayer
在线教程会在一个函数内创建一个 AVAudioPlayer
,AVAudioPlayer
对象的播放和停止函数不能直接从其他函数使用。问题是我想要另一个函数来停止来自 AVAudioPlayer
的声音。这看起来很简单,通过初始化 class 顶部的对象,希望它可以访问,但是在 Swift3
中,AVAudioPlayer
的 init
函数包含一个 throw
和声音文件的参数。 Swift 不允许我们在 属性 初始化器中使用实例成员,所以我一直在思考如何编写它。
此时我 运行 遇到的唯一错误是在创建 "backgroundMusicPlayer":
时不允许在 属性 初始化程序中使用实例成员
import UIKit
import AVFoundation
class MadLibOneViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var thePlace: UITextField!
@IBOutlet weak var theVerb: UITextField!
@IBOutlet weak var theNumber: UITextField!
@IBOutlet weak var theTemplate: UITextView!
@IBOutlet weak var theStory: UITextView!
@IBOutlet weak var generateStoryButton: UIButton!
@IBOutlet weak var proceedToNextMadLib: UIButton!
//var backgroundMusicPlayer = AVAudioPlayer()
var error:NSError?
var path = Bundle.main.path(forResource: "bensound-cute", ofType: "mp3")
var url: NSURL {
return NSURL(fileURLWithPath: path!)
}
var backgroundMusicPlayer: AVAudioPlayer = try AVAudioPlayer(contentsOf: url as URL, error: &error)
@IBAction func createStory(_ sender: AnyObject) {
theStory.text=theTemplate.text
theStory.text=theStory.text.replacingOccurrences(of: "<place>", with: thePlace.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<verb>", with: theVerb.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<number>", with: theNumber.text!)
generateStoryButton.isHidden=true
proceedToNextMadLib.isHidden=false
}
@IBAction func showNextStory(_ sender: AnyObject) {
view.backgroundColor=UIColor.green
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewController(withIdentifier: "MadLibTwoViewController") as! MadLibTwoViewController
self.present(resultViewController, animated:true, completion:nil)
}
@IBAction func hideKeyboard(_ sender: AnyObject) {
thePlace.resignFirstResponder()
theVerb.resignFirstResponder()
theNumber.resignFirstResponder()
theTemplate.resignFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
proceedToNextMadLib.isHidden=true
view.backgroundColor = UIColor.purple
// Do any additional setup after loading the view.
self.theVerb.delegate = self
self.thePlace.delegate = self
self.theNumber.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
为此您需要使用 Lazy initialisation/instantiation
。在您的情况下,这就是您需要做的全部。
lazy var player: AVAudioPlayer = {
[unowned self] in
do {
return try AVAudioPlayer.init(contentsOf: self.url)
}
catch {
return AVAudioPlayer.init()
}
}()
想了解更多Lazy Initialisation
this is a good read. The interesting thing in your case is that the initialiser throws
. I think this forum discussion有一点想法很有帮助。
通常的 AVAudioPlayer
在线教程会在一个函数内创建一个 AVAudioPlayer
,AVAudioPlayer
对象的播放和停止函数不能直接从其他函数使用。问题是我想要另一个函数来停止来自 AVAudioPlayer
的声音。这看起来很简单,通过初始化 class 顶部的对象,希望它可以访问,但是在 Swift3
中,AVAudioPlayer
的 init
函数包含一个 throw
和声音文件的参数。 Swift 不允许我们在 属性 初始化器中使用实例成员,所以我一直在思考如何编写它。
此时我 运行 遇到的唯一错误是在创建 "backgroundMusicPlayer":
时不允许在 属性 初始化程序中使用实例成员import UIKit
import AVFoundation
class MadLibOneViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var thePlace: UITextField!
@IBOutlet weak var theVerb: UITextField!
@IBOutlet weak var theNumber: UITextField!
@IBOutlet weak var theTemplate: UITextView!
@IBOutlet weak var theStory: UITextView!
@IBOutlet weak var generateStoryButton: UIButton!
@IBOutlet weak var proceedToNextMadLib: UIButton!
//var backgroundMusicPlayer = AVAudioPlayer()
var error:NSError?
var path = Bundle.main.path(forResource: "bensound-cute", ofType: "mp3")
var url: NSURL {
return NSURL(fileURLWithPath: path!)
}
var backgroundMusicPlayer: AVAudioPlayer = try AVAudioPlayer(contentsOf: url as URL, error: &error)
@IBAction func createStory(_ sender: AnyObject) {
theStory.text=theTemplate.text
theStory.text=theStory.text.replacingOccurrences(of: "<place>", with: thePlace.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<verb>", with: theVerb.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<number>", with: theNumber.text!)
generateStoryButton.isHidden=true
proceedToNextMadLib.isHidden=false
}
@IBAction func showNextStory(_ sender: AnyObject) {
view.backgroundColor=UIColor.green
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewController(withIdentifier: "MadLibTwoViewController") as! MadLibTwoViewController
self.present(resultViewController, animated:true, completion:nil)
}
@IBAction func hideKeyboard(_ sender: AnyObject) {
thePlace.resignFirstResponder()
theVerb.resignFirstResponder()
theNumber.resignFirstResponder()
theTemplate.resignFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
proceedToNextMadLib.isHidden=true
view.backgroundColor = UIColor.purple
// Do any additional setup after loading the view.
self.theVerb.delegate = self
self.thePlace.delegate = self
self.theNumber.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
为此您需要使用 Lazy initialisation/instantiation
。在您的情况下,这就是您需要做的全部。
lazy var player: AVAudioPlayer = {
[unowned self] in
do {
return try AVAudioPlayer.init(contentsOf: self.url)
}
catch {
return AVAudioPlayer.init()
}
}()
想了解更多Lazy Initialisation
this is a good read. The interesting thing in your case is that the initialiser throws
. I think this forum discussion有一点想法很有帮助。