iOS Swift: iAd Interstitial leaves black screen af

2019-09-07 09:30发布

问题:

I'm trying to add ads into my game, every time the user loses I present my game over view controller. On occasions, when an ad loads I have a full screen interstitial is shown on top of the game over screen.

My problem is the interstitial doesn't come with a close button, so I added one so the user doesn't feel forced to tap on the ad every time it comes up. When the user clicks the close button, the ad is dismissed and the game over view controller is once again shown. Problem is, once in a while (at random, maybe the first time or after a couple of runs through) the ad is dismissed and leaves a black screen.

Any ideas why this is happening? I've been scratching my head for a few days trying to figure this out.

Thanks!! Here is my code:

// Ad variables
var interstitialAdView: UIView = UIView()
var interstitial:ADInterstitialAd!
var intersitialTracker = false
var closeButton:UIButton!

override func viewDidAppear(animated: Bool) {
    if !intersitialTracker {
            loadInterstitialAd()
    }
}

// Buttons to restart game, and return to home screen
@IBAction func restartButtonPressed(sender: AnyObject) {

    intersitialTracker = false
    interstitial = nil
    delegate?.gameOverViewControllerDidPressRestart(self)

}

@IBAction func homeButtonPressed(sender: AnyObject) {
    interstitial = nil
    delegate?.gameOverViewControllerDidPressHomebutton(self)


}

func loadInterstitialAd() {
    if interstitial != nil {
        interstitial.delegate = nil
    }
    interstitial = ADInterstitialAd()
    interstitial.delegate = self
    intersitialTracker = true
}

func interstitialAdWillLoad(interstitialAd: ADInterstitialAd!) {
}

func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
    interstitialAdView = UIView()
    interstitialAdView.frame = self.view.bounds
    view.addSubview(interstitialAdView)

    closeButton = UIButton(frame: CGRect(x: 20, y:  20, width: 20, height:20))
    closeButton.setBackgroundImage(UIImage(named: "close"), forState: UIControlState.Normal)


    closeButton.addTarget(self, action: Selector("close"), forControlEvents: UIControlEvents.TouchDown)
    self.view.addSubview(closeButton)
    interstitialAd.presentInView(interstitialAdView)
}

// Called when user leaves the ad
func interstitialAdActionDidFinish(interstitialAd: ADInterstitialAd!) {
    interstitialAdView.removeFromSuperview()
    closeButton.removeFromSuperview()
    interstitial = nil
    closeButton = nil
}

// Called when user goes in ad
func interstitialAdActionShouldBegin(interstitialAd: ADInterstitialAd!, willLeaveApplication willLeave: Bool) -> Bool {
    return true

}

func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) {
}

func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) {
    interstitialAdView.removeFromSuperview()
    closeButton.removeFromSuperview()
    interstitial = nil
    closeButton = nil
}

// Close button for ads
func close() {
    if closeButton != nil {
        interstitialAdView.removeFromSuperview()
        closeButton.removeFromSuperview()
        interstitial = nil
        closeButton = nil
    }
}

Sorry for the lengthy post, thanks!!!!!

回答1:

Not entirely sure why this is happening to you but one way to work around it is to call the function that shows the game over screen. I can't tell exactly which line of code does by the above code you have given but it could look something like this;

func close() {
if closeButton != nil {
    interstitialAdView.removeFromSuperview()
    closeButton.removeFromSuperview()
    interstitial = nil
    closeButton = nil
    self.GameOverScreen()
}


回答2:

Had the same problem, where it would show a black screen after closing the ad.

I ended up using a UIViewController to contain the ad, and then dismissed the view controller upon the ad finishing. This is much cleaner and gets you the presenting transition for free.

Here's what the code looks like to present the ad:

- (void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd
{
    UIViewController *controller = [[UIViewController alloc] init];
    [self.iadInterstitial presentInView:controller.view];
    // Nearly everyone has this logic in their UIViewController. So you may
    // have to replace 'self.viewController' with just 'self'.
    [self.viewController presentViewController:controller animated:YES completion:nil];
}

Here's what the code looks like to dismiss:

- (void)interstitialAdActionDidFinish:(ADInterstitialAd *)interstitialAd
{
    [self.viewController dismissViewControllerAnimated:YES completion:^{
        self.iadInterstitial.delegate = nil;
        self.iadInterstitial = nil;
    }];
}


回答3:

I figured it out after some time, I removed all statements where interstitial was assigned nil, instead I just did it when I exited the view controller. The screen stopped getting black after that. No sure why this worked, but it did. If someone wants to shine some light it will be welcomed!