Question

I've been trying to figure out how to hide and show iAds in my Spritekit Scenes. Currently I have it setup like this:

ViewController.h

#import <UIKit/UIKit.h>
#import <SpriteKit/SpriteKit.h>
#import <iAd/iAD.h>


@interface ViewController : UIViewController <ADBannerViewDelegate> {

    ADBannerView *adView;

}

-(void)showsBanner;
-(void)hidesBanner;



@end

ViewController.m

#import "ViewController.h"
#import <UIKit/UIKit.h>
#import <iAd/iAD.h>
#import "MyScene.h"

#import <SpriteKit/SpriteKit.h>


@implementation ViewController

- (void)viewDidLoad
{

    [super viewDidLoad];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    skView.showsFPS = NO;
    skView.showsNodeCount = NO;

    // Create and configure the scene.
    SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [skView presentScene:scene];
    self.canDisplayBannerAds = YES;

    adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
    adView.frame = CGRectOffset(adView.frame, 0, 0.0f);
    adView.delegate=self;
    [self.view addSubview:adView];

    self.bannerIsVisible=NO;

}

-(void)bannerViewDidLoadAd:(ADBannerView *)banner {
    if (!self.bannerIsVisible) {
        [UIView beginAnimations:@"animatedAdBannerOn" context:NULL];
        banner.frame = CGRectOffset(banner.frame, 0.0, 0.0);
        [UIView commitAnimations];
        self.bannerIsVisible = YES;
    }}

-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
    if (!self.bannerIsVisible) {
        [UIView beginAnimations:@"animatedAdBannerOff" context:NULL];
        banner.frame = CGRectOffset(banner.frame, 0.0, 0.0);
       [adView setAlpha:0];
        [UIView commitAnimations];
        self.bannerIsVisible = NO;
    }
}

-(void)hidesBanner {

    NSLog(@"HIDING BANNER");
    [adView setAlpha:0];
    self.bannerIsVisible = NO;
}


-(void)showsBanner {

    NSLog(@"SHOWING BANNER");
    [adView setAlpha:1];
    self.bannerIsVisible = YES;

}


etc...


@end

Then in my scene I grab my viewcontroller with a pointer:

ViewController *controller;


controller = [[ViewController alloc] init];
[controller hidesBanner];

My nslog runs in the console so I know it's going through. But the banner won't hide. Any thoughts? I'm pretty new with objective c so I have a feeling I'm just doing something dumb.

Was it helpful?

Solution

Like Huygamer said, you're creating a new instance of a view controller so when you call your method [controller hidesBanner]; you're referring to another object.

The best approach here is to use NSNotificationCenter: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

And send a message to your viewcontroller whenever you want to hide or show your ad:

ViewController.m

 - (void)viewDidLoad
 {

        [super viewDidLoad];

         //Add view controller as observer
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"hideAd" object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"showAd" object:nil];

        // Configure the view.
        SKView * skView = (SKView *)self.view;
        skView.showsFPS = NO;
        skView.showsNodeCount = NO;

        // Create and configure the scene.
        SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
        scene.scaleMode = SKSceneScaleModeAspectFill;

        // Present the scene.
        [skView presentScene:scene];
        self.canDisplayBannerAds = YES;

        adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
        adView.frame = CGRectOffset(adView.frame, 0, 0.0f);
        adView.delegate=self;
        [self.view addSubview:adView];

        self.bannerIsVisible=NO;  
 }

    //Handle Notification
 - (void)handleNotification:(NSNotification *)notification
 { 
    if ([notification.name isEqualToString:@"hideAd"]) {
        [self hidesBanner];
    }else if ([notification.name isEqualToString:@"showAd"]) {
        [self showBanner];
    }
 }

And in your scene:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"showAd" object:nil]; //Sends message to viewcontroller to show ad.

 [[NSNotificationCenter defaultCenter] postNotificationName:@"hideAd" object:nil]; //Sends message to viewcontroller to hide ad.

OTHER TIPS

Of course, there are 2 object and why you think it can do?

If you want to access the parent of skscene just do this

UIViewController *vc = self.view.window.rootViewController;

You can access the parent of this skscene and you can do hideBanner at the parent of this scene. Simple?

Here is what I did to make it work with SpriteKit Scenes (Xcode 6.1 and iOS 8.1 on iPhone 6):

Step 1- Add #import <"iAd/iAd.h"> in MyScene.h header file

Step 2- Make sure you declare your MyScene class to implement protocol in MyScene.h header file.

Step 3- Add the following code lines in your MyScene.m file inside -(Void)didMoveToView:(SKView *)view function.

ADBannerView* banner=[[ADBannerView alloc]initWithFrame:CGRectZero];
CGRect bannerFrame =CGRectMake(0, 667, self.view.frame.size.width, 0);
banner.frame=bannerFrame;
[self.view addSubview:banner];
banner.delegate=self;

Step 4- Implement the two methods of iAd

-(void)bannerViewDidLoadAd:(ADBannerView *)banner
 {
   CGRect bannerFrame =CGRectMake(0, 667-50, self.view.frame.size.width, 0);
   [UIView beginAnimations:nil context:nil];
   [UIView setAnimationDuration:1];
   banner.frame=bannerFrame;
   [UIView commitAnimations];

  }

 -(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
 {
   CGRect bannerFrame =CGRectMake(0, 667, self.view.frame.size.width, 0);
   [UIView beginAnimations:nil context:nil];
   [UIView setAnimationDuration:1];
   banner.frame=bannerFrame;
   [UIView commitAnimations];
 }

The above code will move the Ad frame to scene when there is an Ad and will remove the frame if no Ad by animating the movement. Note that the last number in the frame rect is 0. It doesn't matter what you put there, the banner hight is fixed and doesn't change (50 pt).

Step 5- Respond to Ad actions by this code:

  -(void)bannerViewActionDidFinish:(ADBannerView *)banner
   {
    [self startTimer];

   }

   -(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
     {

       [gameTimer invalidate];

       return YES;
      }

This code will stop the game timer when a user clicks on the banner and resumes the game timer after the user returns back to the game. You can add your own code for saving and retrieving game data here.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top