如何在不同的SpriteKit场景中显示iAd横幅

时间:2023-01-22 23:08:26

I made simple game with Swift and SpriteKit. Everything seems to work but I have a problem with my iAd Setup. I only want to show the ad banner in specific scenes (main menu and game over) not during the gameplay. My iAd setup works but only if it is displayed all the time. My last attempt to fix it was with the NSNotificationCenter method. I have done it as I have seen it in other question/answers here but the app crashes immediately after launch. Hope that someone could help me. Just let me know if you need more of my code. Thanks in advance.

我用Swift和SpriteKit做了简单的游戏。一切似乎都有效,但我的iAd设置有问题。我只想在特定场景(主菜单和游戏结束)中展示广告横幅而不是在游戏过程中。我的iAd设置可以正常工作,但前提是它始终显示。我最后一次修复它的尝试是使用NSNotificationCenter方法。我已经完成了,因为我已经在其他问题/答案中看到了它,但应用程序在发布后立即崩溃。希望有人能帮助我。如果您需要更多我的代码,请告诉我。提前致谢。

GameViewController.swift

GameViewController.swift

class GameViewController: UIViewController, ADBannerViewDelegate {

var adBannerView = ADBannerView(frame: CGRect.zeroRect)

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleNotification", name: "hideAd", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleNotification", name: "showAd", object: nil)

    self.adBannerView.delegate = self
    self.adBannerView.hidden = true
    adBannerView.center = CGPoint(x: adBannerView.center.x, y: view.bounds.size.height - adBannerView.frame.size.height / 2)
    view.addSubview(adBannerView)

    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
        // Configure the view.
        let skView = self.view as SKView

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        var scene: SKScene = MainMenu(size: skView.bounds.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        skView.presentScene(scene)
    }
}

func handleNotification(notification: NSNotification){
    if notification.name == "hideAd"{
        adBannerView.hidden = true
    }else if notification.name == "showAd"{
        adBannerView.hidden = false
    }
}

//iAD Setup
func bannerViewWillLoadAd(banner: ADBannerView!) {
    println("Ad loads")
}

func bannerViewDidLoadAd(banner: ADBannerView!){
    println("Ad loaded")
    self.adBannerView.hidden = false
}

func bannerViewActionDidFinish(banner: ADBannerView!) {
    println("resume scene")
    let skView = self.view as SKView
    skView.paused = false
}

func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
    println("pause scene")
    let skView = self.view as SKView
    skView.paused = true
    return true
}

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    println("Failed to load ad")
    self.adBannerView.hidden = true
}   more code.... 

MainMenu.swift

MainMenu.swift

class MainMenu: SKScene{

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override init(size:CGSize){
    super.init(size: size)

    NSNotificationCenter.defaultCenter().postNotificationName("showAd", object: nil)
more code...

2 个解决方案

#1


8  

This works for me

这对我有用

In my view controller I have this code:

在我的视图控制器中,我有这个代码:

// Banner Ad

// 横幅广告

var SH = UIScreen.mainScreen().bounds.height
let transition = SKTransition.fadeWithDuration(1) 
var UIiAd: ADBannerView = ADBannerView()

override func viewWillAppear(animated: Bool) {
    var BV = UIiAd.bounds.height
    UIiAd.delegate = self
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0)
    self.view.addSubview(UIiAd)
}

override func viewWillDisappear(animated: Bool) {
    UIiAd.delegate = nil
    UIiAd.removeFromSuperview()
}

func bannerViewDidLoadAd(banner: ADBannerView!) {
    var BV = UIiAd.bounds.height
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.alpha = 1 // Fade in the animation
    UIView.commitAnimations()
}

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1)
    UIiAd.alpha = 0
    UIView.commitAnimations()
}

func showBannerAd() {
    UIiAd.hidden = false
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH - BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

func hideBannerAd() {
    UIiAd.hidden = true
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.UIiAd.hidden = true
    self.UIiAd.alpha = 0

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "hideBannerAd", name: "hideadsID", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "showBannerAd", name: "showadsID", object: nil)


    let scene = GameScene()
    // Configure the view.
    let skView = self.view as SKView
    skView.showsFPS = false
    skView.showsNodeCount = false

    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = true

    /* Set the scale mode to scale to fit the window */
    scene.scaleMode = .AspectFit
    scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    scene.size = skView.bounds.size
    skView.presentScene(scene, transition: transition)
}

To display it in the scene I want (for me it's the GameOver scene) I did this:

要在我想要的场景中显示它(对我而言,它是GameOver场景)我这样做:

override func didMoveToView(view: SKView) {

    showAds()
    // Rest of your code here...
}

func showAds(){
    NSNotificationCenter.defaultCenter().postNotificationName("showadsID", object: nil)
}

Basically this code creates a banner off the scene, and when the banner is loaded and the scene gets called, it slides up from the bottom. When you switch scenes, it offsets it again and when you come back to that scene, it slides up from the bottom again. If the banner doesn't load, it's off screen so no worries about it showing a white bar. Also, it sets the alpha to 0 if it doesn't load just in case (makes it invisible). Hope this helps.

基本上,此代码会在场景中创建一个横幅,当加载横幅并调用场景时,它会从底部向上滑动。当你切换场景时,它会再次偏移它,当你回到那个场景时,它会再次从底部向上滑动。如果横幅没有加载,它就会关闭屏幕,所以不用担心它会显示白色条。此外,它将alpha设置为0,如果它不加载以防万一(使其不可见)。希望这可以帮助。

#2


1  

I USE THIS TO PRESENT THE iAd Banner in subview

我使用它来在子视图中呈现iAd Banner

var vc = self.view?.window?.rootViewController vc?.view.addSubview(adView!)

var vc = self.view?.window?.rootViewController vc?.view.addSubview(adView!)

When I want to hide it when in the game (because iAd reduce FPS) I call

当我想在游戏中隐藏它时(因为iAd减少FPS)我打电话

adView!.removeFromSuperview()

AD浏览!.removeFromSuperview()

When the user finished the Game just add

当用户完成游戏时,只需添加即可

         var vc = self.view?.window?.rootViewController
        vc?.view.addSubview(adView!)

to show the iAd banner again

再次显示iAd横幅

BUT YOU NEED TO IMPLEMENT THIS CODE IN GameViewController

但是你需要在GameViewController中实现这个代码

class GameViewController: ADBannerViewDelegate (you needed this too) also don't forget to import iAd at the top of gameviewcontroller also import iAd framework to the project

class GameViewController:ADBannerViewDelegate(你也需要这个)也不要忘记在gameviewcontroller的顶部导入iAd也将iAd框架导入到项目中

override func viewDidLoad() {
    self.ShowAd()

//Have this in view didLoad too

//在视图中也有这个

     func ShowAd() {
        super.viewDidLoad()
        adView = ADBannerView(adType: ADAdType.Banner)
        adView!.delegate = self

    }
    func bannerViewDidLoadAd(banner: ADBannerView!) {
        self.view.addSubview(adView!)
        self.view.layoutIfNeeded()
        println("Pass")
    }

    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
        adView!.removeFromSuperview()
        /*var alert = UIAlertController(title: "iAd Message", message:
            "iAd Fail To Load", preferredStyle: UIAlertControllerStyle.Alert)

        self.presentViewController(alert, animated: false, completion: nil)

        alert.addAction(UIAlertAction(title: "dismiss", style: UIAlertActionStyle.Default,
            handler: nil))
        self.view.layoutIfNeeded()*/
        println("fail")
    }

#1


8  

This works for me

这对我有用

In my view controller I have this code:

在我的视图控制器中,我有这个代码:

// Banner Ad

// 横幅广告

var SH = UIScreen.mainScreen().bounds.height
let transition = SKTransition.fadeWithDuration(1) 
var UIiAd: ADBannerView = ADBannerView()

override func viewWillAppear(animated: Bool) {
    var BV = UIiAd.bounds.height
    UIiAd.delegate = self
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0)
    self.view.addSubview(UIiAd)
}

override func viewWillDisappear(animated: Bool) {
    UIiAd.delegate = nil
    UIiAd.removeFromSuperview()
}

func bannerViewDidLoadAd(banner: ADBannerView!) {
    var BV = UIiAd.bounds.height
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.alpha = 1 // Fade in the animation
    UIView.commitAnimations()
}

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1)
    UIiAd.alpha = 0
    UIView.commitAnimations()
}

func showBannerAd() {
    UIiAd.hidden = false
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH - BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

func hideBannerAd() {
    UIiAd.hidden = true
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.UIiAd.hidden = true
    self.UIiAd.alpha = 0

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "hideBannerAd", name: "hideadsID", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "showBannerAd", name: "showadsID", object: nil)


    let scene = GameScene()
    // Configure the view.
    let skView = self.view as SKView
    skView.showsFPS = false
    skView.showsNodeCount = false

    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = true

    /* Set the scale mode to scale to fit the window */
    scene.scaleMode = .AspectFit
    scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    scene.size = skView.bounds.size
    skView.presentScene(scene, transition: transition)
}

To display it in the scene I want (for me it's the GameOver scene) I did this:

要在我想要的场景中显示它(对我而言,它是GameOver场景)我这样做:

override func didMoveToView(view: SKView) {

    showAds()
    // Rest of your code here...
}

func showAds(){
    NSNotificationCenter.defaultCenter().postNotificationName("showadsID", object: nil)
}

Basically this code creates a banner off the scene, and when the banner is loaded and the scene gets called, it slides up from the bottom. When you switch scenes, it offsets it again and when you come back to that scene, it slides up from the bottom again. If the banner doesn't load, it's off screen so no worries about it showing a white bar. Also, it sets the alpha to 0 if it doesn't load just in case (makes it invisible). Hope this helps.

基本上,此代码会在场景中创建一个横幅,当加载横幅并调用场景时,它会从底部向上滑动。当你切换场景时,它会再次偏移它,当你回到那个场景时,它会再次从底部向上滑动。如果横幅没有加载,它就会关闭屏幕,所以不用担心它会显示白色条。此外,它将alpha设置为0,如果它不加载以防万一(使其不可见)。希望这可以帮助。

#2


1  

I USE THIS TO PRESENT THE iAd Banner in subview

我使用它来在子视图中呈现iAd Banner

var vc = self.view?.window?.rootViewController vc?.view.addSubview(adView!)

var vc = self.view?.window?.rootViewController vc?.view.addSubview(adView!)

When I want to hide it when in the game (because iAd reduce FPS) I call

当我想在游戏中隐藏它时(因为iAd减少FPS)我打电话

adView!.removeFromSuperview()

AD浏览!.removeFromSuperview()

When the user finished the Game just add

当用户完成游戏时,只需添加即可

         var vc = self.view?.window?.rootViewController
        vc?.view.addSubview(adView!)

to show the iAd banner again

再次显示iAd横幅

BUT YOU NEED TO IMPLEMENT THIS CODE IN GameViewController

但是你需要在GameViewController中实现这个代码

class GameViewController: ADBannerViewDelegate (you needed this too) also don't forget to import iAd at the top of gameviewcontroller also import iAd framework to the project

class GameViewController:ADBannerViewDelegate(你也需要这个)也不要忘记在gameviewcontroller的顶部导入iAd也将iAd框架导入到项目中

override func viewDidLoad() {
    self.ShowAd()

//Have this in view didLoad too

//在视图中也有这个

     func ShowAd() {
        super.viewDidLoad()
        adView = ADBannerView(adType: ADAdType.Banner)
        adView!.delegate = self

    }
    func bannerViewDidLoadAd(banner: ADBannerView!) {
        self.view.addSubview(adView!)
        self.view.layoutIfNeeded()
        println("Pass")
    }

    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
        adView!.removeFromSuperview()
        /*var alert = UIAlertController(title: "iAd Message", message:
            "iAd Fail To Load", preferredStyle: UIAlertControllerStyle.Alert)

        self.presentViewController(alert, animated: false, completion: nil)

        alert.addAction(UIAlertAction(title: "dismiss", style: UIAlertActionStyle.Default,
            handler: nil))
        self.view.layoutIfNeeded()*/
        println("fail")
    }