当从另一个类调用的函数

时间:2019-01-22 16:02:02

标签: ios swift segue

我有一个应用介绍视频部分。故事板具有一个segue“ toMainMenu”,该链接链接到另一个故事板视图控制器。

IntroVideoVC内部有两个类:-

class IntroVideoVC: UIViewController {
    var videoView: IntroVideoView!

    override func viewDidLoad() {
        videoView = IntroVideoView(controller: self)
        self.view.addSubview(videoView)

       let tap = UITapGestureRecognizer(target: self, action: #selector(tappedVideo))
       view.addGestureRecognizer(tap)
    }

    @objc func tappedVideo() {
        videoFinished();
    }

    func videoFinished() {
        self.performSegue(withIdentifier: "toMainMenu", sender: self)
    }   
}

class IntroVideoView: UIView {
    init(controller: UIViewController) {
        super.init(frame: CGRect(x: 0, y: 0, w: 0, h: 0))
        self.controller = controller
        ...
    }

    func handleVideo(videoPlayer: AVPlayer) {
        ...
        IntroVideoVC().videoFinished()
    }
}

如果我点击视频,它将正确执行segue,但是如果我让视频端依次调用IntroVideoViews-> handleVideo()方法,则会崩溃,表明它没有标识为“ toMainMenu”的segue。

我想我理解原因,但是不确定如何解决这个新问题。我相信这是因为handleVideo()使用IntroVideoVC作为单例,因此丢失了对IntroVideoVC控制器的引用!我也许(读:可能)是错误的,但这就是我认为可能导致此问题的原因。

只需要在正确的方向上轻推

预先感谢

1 个答案:

答案 0 :(得分:1)

您可以使用协议来解决该问题,就像这样:

protocol IntroVideoDelegate {
    func videoFinished()
}
class IntroVideoVC: UIViewController, IntroVideoDelegate {
    var videoView: IntroVideoView!

    override func viewDidLoad() {
        videoView = IntroVideoView(controller: self)
        videoView.videoDelegate = self
        self.view.addSubview(videoView)

       let tap = UITapGestureRecognizer(target: self, action: #selector(tappedVideo))
       view.addGestureRecognizer(tap)
    }

    @objc func tappedVideo() {
        videoFinished();
    }

    func videoFinished() {
       self.performSegue(withIdentifier: "toMainMenu", sender: self)
    }   
}

class IntroVideoView: UIView {
    videoDelegate: IntroVideoDelegate?
    init(controller: UIViewController) {
        super.init(frame: CGRect(x: 0, y: 0, w: 0, h: 0))
        self.controller = controller
        ...
    }

    func handleVideo(videoPlayer: AVPlayer) {
        ...
        videoDelegate.videoFinished()
    }
}

请记住,videoView仍是IntroVideoVC的子视图,因此,如果应用回到该VC,则用户将看到它,因此,如果您不希望发生这种情况,请确保使用以下命令将其删除:

videoView.removeFromSuperview()

在videoFinished()函数中

如果您想从视图中运行VC函数,则应获取IntroVideoView的父级,方法如下:documentation但我很确定它会破坏MVC