从另一个ViewController在swift中调用函数
我已经看了Stackoverflow,但我无法得到答案。 我想要创build停止在另一个ViewController中播放声音的函数。 但是,当我点击停止button时,它破解并显示“EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0)”。 这是我的代码。
第一个ViewController
import UIKit import AVFoundation class FirstVC: UIViewController { var metronome: AVAudioPlayer! override func viewDidLoad() { super.viewDidLoad() do { let resourcePath1 = Bundle.main.path(forResource: "music", ofType: "mp3") let url = NSURL(fileURLWithPath: resourcePath1!) try metronome = AVAudioPlayer(contentsOf: url as URL) metronome.prepareToPlay() metronome.play() } catch let err as NSError { print(err.debugDescription) } }
另一个Viewcontroller是
import UIKit class SecondVC: UIViewController { var metronomePlay = FirstVC() @IBAction func stopBtnPressed(_ sender: Any) { metronomePlay.metronome.stop() //"EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" } }
如果你想从one_view_controller按下button,并停止在另一个视图控制器上的声音,然后按照此。
遵循以下步骤:
步骤1 :
添加这个代码在你的视图控制器,你想按下button单击停止声音。
@IBAction func btnStopSound(_ sender: AnyObject) { NSNotificationCenter.defaultCenter().postNotificationName("stopSoundNotification", object: nil) }
第2步:
现在是最后一步。 现在将下面的代码添加到您的结果视图控制器,您想要自动停止声音。
func loadList(notification: NSNotification){ metronomePlay.metronome.stop() } override func viewWillAppear(animated: Bool) { NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadList:",name:"stopSoundNotification", object: nil) }
现在在编码中实现这个代码。 希望对你有效。
您正在创build一个FirstVC的新副本,并在尚未初始化的东西上调用stop。
在这种情况下,你应该真的使用委托,就像
protocol controlsAudio { func startAudio() func stopAudio() } class FirstVC: UIViewController, controlsAudio { func startAudio() {} func stopAudio() {} // later in the code when you present SecondVC func displaySecondVC() { let vc = SecondVC() vc.delegate = self self.present(vc, animated: true) } } class SecondVC: UIViewController { var delegate: controlsAudio? // to start audio call self.delegate?.startAudio) // to stop audio call self.delegate?.stopAudio) }
所以你将第一个VC传给第二个VC,所以当你调用这些函数的时候,你正在使用实际的FirstVC,而不是创build一个新的VC。
你可以做这个没有协议,如果你喜欢通过replacevar delegate: controlsAudio?
用var firstVC: FirstVC?
并分配,但我不会推荐它
您正在使用FirstVC
viewDidLoad
方法初始化metronome
。 在SecondVC
,您将初始化metronomePlay
作为存储属性,但从不要求ViewController的视图,因此FirstVC
viewDidLoad
不会被调用,从而导致metronome
(存储属性)未初始化。
var metronomePlay = FirstVC()
您正在FirstVC上创build一个新的实例,而应该在已经加载的FirstVC的同一个实例上执行该函数。
你在初始化FirstVC
中的第一个FirstVC
viewDidLoad
,这将不会发生,直到加载在SecondVC
实例化的metronomePlay
播放的视图。 在实际调用metronomePlay.metronome
之前,您必须首先在SecondVC
上调用_ = metronomePlay.view
metronomePlay.metronome
。
更新@Scriptable的Swift 4的答案
步骤1 :
添加这个代码在你的视图控制器,你想按下button单击停止声音。
@IBAction func btnStopSound(_ sender: AnyObject) { notificationCenter.post(name: Notification.Name("stopSoundNotification"), object: nil) }
第2步:
现在是最后一步。 现在将下面的代码添加到您想要自动停止声音的结果视图控制器中。
func functionName (notification: NSNotification) { metronomePlay.metronome.stop() } override func viewWillAppear(animated: Bool) { NSNotificationCenter.defaultCenter().addObserver(self, selector: "functionName",name:"stopSoundNotification", object: nil) }
在SecondVC中试试这个。 var metronomePlay = FirstVC()。节拍器
- AutoLayout视图使应用程序在popViewController上崩溃
- Swift – Error'Expected','separator'和'Expected expression in list of expressions'
- Firebase云消息传递不会创build推送通知,但会获取信息
- 如何获得AFNetworking 2.0的下载进度?
- 将代码从视图控制器中移出并将其移动到执行Swift所有function的“Brain”
- dyld:Library未加载:@ rpath / libswiftCore.dylib。 问题依然存在
- Swift UITextField子类以编程方式处理文本更改
- SFSafariViewController presentViewControlleranimation
- 用户多长时间创build一个post,NSDate(),操作创build“post时间”的格式