如何在 UIView class 中调用 fromRootViewController 方法?

How do I call a fromRootViewController method within a UIView class?

编辑:这是一个非常初级的问题,所以我提前道歉

这是我正在尝试破解的家庭作业的子部分,但似乎有点不可能。我已经在 Google Admob 上为我的 UIView 实现了 GADRewardBasedVideoAdDelegate 以获取奖励广告,并设法在 "PopUp" 中实现了该委托的所有其他实例,它是 UIView 的子class。

但是,这一种方法似乎无法实现,即:

    if GADRewardBasedVideoAd.sharedInstance().isReady == true {    
        GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: self)
         }

问题出在代码的“.present(fromRootViewController: self) 部分,因为 self 指的不是 ViewController 而是 UIView()。

老实说,我不知道如何解决这种情况,所以我在这个问题上的尝试没有什么可展示的。如果能就此主题提供任何指导,我将不胜感激,我已经在这里停留了 2 天的大部分时间。

这是弹出窗口 class 以防它有助于使我的代码更清晰

import UIKit
import GoogleMobileAds

class Popup: UIView, GADRewardBasedVideoAdDelegate {

    func rewardBasedVideoAd(_ rewardBasedVideoAd: GADRewardBasedVideoAd, didRewardUserWith reward: GADAdReward) {
        let vc = MainVC()
        vc.lifeNumber += 3
        vc.numberOfLivesLabel.text = "\(vc.lifeNumber)"
    }

    func rewardBasedVideoAdDidClose(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
        GADRewardBasedVideoAd.sharedInstance().load(GADRequest(), withAdUnitID: "ca-app-pub-3940256099942544/1712485313")
    }


    let playButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(named: "icon"), for: .normal)
        button.addTarget(self, action: #selector(play), for: .touchUpInside)
        return button
    }()

    @objc func play() {
        print("Play button pressed.")
        if GADRewardBasedVideoAd.sharedInstance().isReady == true {
            GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: self) //<---------ERRONEOUS CODE
             }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)

        GADRewardBasedVideoAd.sharedInstance().load(GADRequest(), withAdUnitID: "ca-app-pub-3940256099942544/1712485313")
        GADRewardBasedVideoAd.sharedInstance().delegate = self


self.addSubview(popUpContainer)
playButton.centerXAnchor.constraint(equalTo: popUpContainer.centerXAnchor),
    playButton.topAnchor.constraint(equalTo: popUpContainer.topAnchor, constant: 15),
    playButton.heightAnchor.constraint(equalToConstant: 300)
    playButton.widthAnchor.constraint(equalToConstant: 300)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("Could not run init(coder)")
    }
}

这是我的 MainVC()

class MainVC: UIViewController {

    var lifeNumber: Int = 3

    lazy var numberOfLivesLabel: UILabel = {
        let label = UILabel()
        label.text = "\(lifeNumber)"
        label.font = UIFont(name: "Copperplate", size: 25)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let buttonOne: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Hit me!", for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    @objc func buttonPressed() {
        let popUpView = Popup()
        self.view.addSubview(popUpView)
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue

        view.addSubview(buttonOne)
        view.addSubview(numberOfLivesLabel)

        buttonOne.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        buttonOne.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        buttonOne.heightAnchor.constraint(equalToConstant: 300).isActive = true
        buttonOne.widthAnchor.constraint(equalToConstant: 300).isActive = true

        numberOfLivesLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        numberOfLivesLabel.bottomAnchor.constraint(equalTo: buttonOne.topAnchor, constant: 50).isActive = true

    }
}

This code from hacking with swift will help.

    extension UIView {
    func findViewController() -> UIViewController? {
        if let nextResponder = self.next as? UIViewController {
            return nextResponder
        } else if let nextResponder = self.next as? UIView {
            return nextResponder.findViewController()
        } else {
            return nil
        }
    }
}

使用扩展获取弹出窗口父视图控制器。

if GADRewardBasedVideoAd.sharedInstance().isReady == true {    
    GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: self.findViewController())
     }

你可能也想把它放在主队列中

    if GADRewardBasedVideoAd.sharedInstance().isReady == true {    
      DispatchQueue.main.async {
         GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: self.findViewController())
     }
    }