My iAd is white. It looks like bannerViewDidLoadAd is run when the iAd is not fully loaded. It happens only when I show my ViewController first time (application starts). When I go to another controller and return, iAd is loaded properly. Do you have any idea why?
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
_bannerView.hidden = NO;
[self.view setNeedsLayout];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
_bannerView.hidden = YES;
[self.view setNeedsLayout];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!_bannerView) {
_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_bannerView.delegate = self;
_bannerView.hidden = YES;
CGRect bannerFrame = _bannerView.frame;
bannerFrame.origin.y = self.view.bounds.size.height - _bannerView.bounds.size.height;
_bannerView.frame = bannerFrame;
[self.view addSubview:_bannerView];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
_bannerView.delegate = nil;
[_bannerView removeFromSuperview];
_bannerView = nil;
}
Related
I'm trying to handle my iAd via a singleton, since I'm using these banners in several view controllers. Now I'm confused of what do these objects store, since I move them around differently on each view controller when an ad is shown or if an error occured. Here my code:
Singleton:
+ (MySingleton *)sharedInstance {
static dispatch_once_t once;
static MySingleton * sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (id)init
{
if (self = [super init]) {
if ([ADBannerView instancesRespondToSelector:#selector(initWithAdType:)]) {
self.bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
} else {
self.bannerView = [[ADBannerView alloc] init];
}
}
return self;
}
And here how it is initalized:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//iAd
if(![[NSUserDefaults standardUserDefaults] objectForKey:kInAppPurchaseNoAds]){
self.bannerView = [MySingleton sharedInstance].bannerView;
self.bannerView.delegate = self;
self.bannerView.frame = CGRectOffset(self.bannerView.frame, 0, self.view.frame.size.height);
[self.view addSubview:self.bannerView];
}
}
And the delegate methods:
- (void)showBanner
{
if(!self.isBannerVisible){
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.5
animations:^{
//Restore the constraint
self.mainContainerToSuperviewConstraint.constant = 50;
//Move the banner on
self.bannerView.frame = CGRectOffset(self.bannerView.frame, 0, -50);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.isBannerVisible = YES;
}];
}
}
- (void)hideBanner
{
if(self.isBannerVisible){
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.5
animations:^{
//Restore the constraint
self.mainContainerToSuperviewConstraint.constant = 0;
//Move the banner off
self.bannerView.frame = CGRectOffset(self.bannerView.frame, 0, self.bannerView.frame.size.height);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.isBannerVisible = NO;
}];
}
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
[self showBanner];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[self hideBanner];
}
Now what I'm confused is, do I have to check the position of the banner view again if the user was in another view with also an iAd where the rectangle with visible banner was at let's say 75 from the bottom of the screen and not 50? Or do these positions do not influence the AdBannerView but only the single object in each class?! I mean if he was in the other view and there the code moved the Banner to 75 pixels from the bottom, are these 75 pixels stored in my singleton AdView? So the original view had the banner now at 75 and not at 50?
I would suggest against having a singleton for a view - one view instance can be a subview only of 1 view, so you need to track adding/removing it and also you need to set the frame every time you add it again as a subview. You better have some kind of base view controller to share the instantiation logic and the control of the banners.
In my app, I had added the ADBannerView into the UIViewController by code
in .h file
#property (strong, nonatomic) ADBannerView *adBannerView;
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
self.adBannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 518, 320, 50);];
[self.view addSubview:self.adBannerView];
}
#pragma mark - ADBannerViewDelegate
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
NSLog(#"bannerview did not receive any banner due to %#", error);
}
- (void)bannerViewActionDidFinish:(ADBannerView *)banner {
NSLog(#"bannerview was selected");
}
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave {
NSLog(#"banner action should begin");
return YES;
}
- (void)bannerViewWillLoadAd:(ADBannerView *)banner {
NSLog(#"banner will loaded");
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
NSLog(#"banner was loaded");
}
My app is normally, it can show the ADBannerView. But now, I want to remove the ADBannerView out of the UIViewController, then I removed all the lines of code about the ADBannerView. I can build my app, but it cannot run, the error msg is:
Could not instantiate class named ADBannerView
Please help me to remove the ADBannerView. Thank you.
- (void)bannerViewDidLoadAd:(ADBannerView *)banner{
if (!bannerIsVisible){
//LOG_TYPE(#"AD show");
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
// banner is invisible now and moved out of the screen on 50 px
// banner.frame = CGRectOffset(banner.frame, 0, -50);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if (IS_IPHONE_5) {
//LOG_TYPE(#"view height: %f",self.view.bounds.size.height);
self.adView.frame = CGRectMake(0,568-49-50, self.view.frame.size.width, 50);
}
else{
//LOG_TYPE(#"view height: %f",self.view.bounds.size.height);
self.adView.frame = CGRectMake(0,480-49-50, self.view.frame.size.width, 50);
}
}
else{
self.adView.frame = CGRectMake(0,1024-56-50, self.view.frame.size.width, 50);
}
[UIView commitAnimations];
bannerIsVisible = YES;
[self performSelector:#selector(hideAD) withObject:nil afterDelay:6];
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
if (bannerIsVisible){
//LOG_TYPE(#"AD error");
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// banner is visible and we move it out of the screen, due to connection issue
// banner.frame = CGRectOffset(banner.frame, 0, 50);
bannerIsVisible = NO;
[self performSelector:#selector(hideAD) withObject:nil afterDelay:0];
// [self performSelector:#selector(hideAD) withObject:nil afterDelay:5];
}
}
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave{
//LOG_TYPE(#"Banner view is beginning an ad action");
BOOL shouldExecuteAction = YES;
if (!willLeave && shouldExecuteAction){
// stop all interactive processes in the app
// [video pause];
// [audio pause];
}
return shouldExecuteAction;
}
- (void)bannerViewActionDidFinish:(ADBannerView *)banner{
// resume everything you've stopped
// [video resume];
// [audio resume];
}
- (void)hideAD{
//LOG_TYPE(#"Hide AD");
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// banner is visible and we move it out of the screen, due to connection issue
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if (IS_IPHONE_5) {
//LOG_TYPE(#"view height: %f",self.view.bounds.size.height);
self.adView.frame = CGRectMake(0,568-49+50, self.view.frame.size.width, 50);
}
else{
//LOG_TYPE(#"view height: %f",self.view.bounds.size.height);
self.adView.frame = CGRectMake(0,480-49+50, self.view.frame.size.width, 50);
}
}
else{
self.adView.frame = CGRectMake(0,1024-56+50, self.view.frame.size.width, 50);
}
[UIView commitAnimations];
bannerIsVisible = NO;
[self performSelector:#selector(bannerViewDidLoadAd:) withObject:self.adView afterDelay:60];
}
-(void)viewDidLoad{
...
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if (IS_IPHONE_5) {
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0,568-49-50, self.view.frame.size.width, 50)];
}
else{
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0,480-49-50, self.view.frame.size.width, 50)];
}
}
else{
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0,1024-56-50, self.view.frame.size.width, 50)];
}
[self.view addSubview:self.adView];
self.adView.delegate=self;
bannerIsVisible=NO;
self.adView.backgroundColor = [UIColor clearColor];
....
}
if you add ADBannerView in storyboard then remove the IBoutlet of ADBannerView and its delegate.
break connection of below figure for ADBannerView
remove ADBannerViewfrom storyboard and your above code is perfect.
Your error as below.
[self.adView removeFromSuperView];
currently I'm trying to implement iAd in my universal iOS7 app.
This is working absolutly fine on iphone but on the ipad i get this screwed up ads but the bannersize is correct.
is this a known issue? or is there a ipad special implementation I didn't knew?
[edit!]
I'm pretty sure there is only one banner! its really just showing the normal iad ad in that weird way.
If I click on the ad, the fullscreen one is also not right scaled but its shown on the hole screen. Here is my implementation:
- (void)viewDidLoad
{
_adBannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_adBannerView.delegate = self;
_bannerIsVisible = NO;
[self.view addSubview:self.adBannerView];
...
}
- (void)viewDidLayoutSubviews {
CGRect contentFrame = _mainNavigation.frame, bannerFrame = CGRectZero;
bannerFrame.size = [_adBannerView sizeThatFits:contentFrame.size];
if (_adBannerView.bannerLoaded && !_bannerIsVisible) {
contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.origin.y + contentFrame.size.height;
_bannerIsVisible = YES;
} else {
bannerFrame.origin.y = contentFrame.origin.y + contentFrame.size.height;
}
_mainNavigation.frame = contentFrame;
_adBannerView.frame = bannerFrame;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
NSLog(#"didFailToReceiveAdWithError %#", error);
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
And is there a way to show the test ads on a real device?
because I always get "Ad inventory unavailable"!
I have this in my webViewDidFinishLoad:
- (void)setupAdBanner {
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
CGRect adFrame = adView.frame;
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait
|| [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
adView.currentContentSizeIdentifier =
ADBannerContentSizeIdentifierPortrait;
adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
} else {
adView.currentContentSizeIdentifier =
ADBannerContentSizeIdentifierLandscape;
adFrame.size.width = adView.frame.size.width;
adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
}
adView.frame = adFrame;
[self.view addSubview:adView];
}
This overlaps HTML content in my phonegap application. How do I adjust my webview frame sizes to account for the ad banner?
I had this exact problem. I blogged about my solution here http://hawkinbj.wordpress.com/2013/04/16/implement-iad-banner-ads-without-covering-uiwebview-in-phonegap/
You need to implement ADBannerViewDelegateProtocolReference. In MainViewController.h:
#interface MainViewController : CDVViewController <ADBannerViewDelegate>
{
ADBannerView *adView;
}
#end
The rest of the steps are in MainViewController.m.
In webViewDidFinishLoad:
adView.delegate = self;
Add these two methods:
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
CGRect resizedWebView = [super webView].frame;
resizedWebView.size.height = adView.frame.origin.y;
[super webView].frame = resizedWebView;
[self.view bringSubviewToFront:adView];
adView.hidden = NO;
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
CGRect resizedWebView = [super webView].frame;
resizedWebView.size.height = self.view.frame.size.height;
[super webView].frame = resizedWebView;
adView.hidden = YES;
}
The magic is
[self.view bringSubviewToFront:adView];
This is amongst the oddest issues with iOS development I have ever seen. I'm relatively new to iOS development, so I apologize if I'm missing something obvious or my terminology isn't completely correct. If you need clarification, please let me know in the comments and I'll edit my question accordingly.
The Problem
I'm using Three20, so that might have something to do with it. But I have a "Home view" which is basically a series of images that link out to other views (shown in the image below). If I start our in portrait view, all is well.
The next view is a table view, shown below:
YAY! I can rotate and all is right with the world. BUT if I go back to that home view, rotate to landscape, and THEN go to this tabled view, the world breaks.
You'll see that there's a random space added to the right side of my table now. I don't know where and how it came from. Here's my Controller.m file:
#import "FriendTabsController.h"
#import "MyAppApp.h"
#import "JohnDoeManager.h"
#implementation FriendTabsController
#synthesize innerView, segmentedControl, innerController, friendsController, friendRequestsController;
- (void)addBottomGutter:(UIViewController*)controller {
if ([controller isKindOfClass:[TTTableViewController class]]) {
TTTableViewController* tableViewController = (TTTableViewController*)controller;
tableViewController.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0,0,50+44,0);
tableViewController.tableView.contentInset = UIEdgeInsetsMake(0,0,50+44,0);
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Friends";
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.navigationController.navigationBar.tintColor = nil;
friendsController = [[FriendsController alloc] init];
friendRequestsController = [[FriendsController alloc] init];
((FriendsController*)friendRequestsController).friendRequests = YES;
[self addBottomGutter:friendsController];
[self addBottomGutter:friendRequestsController];
innerController = friendsController;
[innerView addSubview:innerController.view];
[innerController viewDidLoad];
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
[self loadBannerAd:(orientation)];
}
-(void) loadBannerAd:(UIInterfaceOrientation)orientation{
MainLayer *mi = [MainLayer getInstance];
if (mi.useJohnDoeAds) {
[[JohnDoeManager sharedInstance] setCurrentViewController:self];
[mi.JohnDoeBanner.view removeFromSuperview];
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
// This is a portait ad
if ([[MyAppUtils getCurrentDevice] isEqualToString:#"iphone"]) {
[mi.JohnDoeBanner setFrame:CGRectMake(0, 410-44, 320, 50)];
}else{
[mi.JohnDoeBanner setFrame:CGRectMake(0, 1024-44-90-20, 768, 90)];
}
} else {
// Landscape
if ([[MyAppUtils getCurrentDevice] isEqualToString:#"iphone"]) {
[mi.JohnDoeBanner setFrame:CGRectMake(0, 320-44-58, 410, 50)];
}else{
[mi.JohnDoeBanner setFrame:CGRectMake((1024-768)/2, 768-44-90-20, 768, 90)];
}
}
[self.view addSubview:mi.JohnDoeBanner.view];
[mi.JohnDoeBanner rollOver];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self loadBannerAd:(toInterfaceOrientation)];
}
- (IBAction)didChangeSegment:(UISegmentedControl *)control {
if (innerController) {
[innerController viewWillDisappear:NO];
[innerController.view removeFromSuperview];
[innerController viewDidDisappear:NO];
}
switch (control.selectedSegmentIndex) {
case 0:
innerController = friendsController;
self.title = #"Friends";
break;
case 1:
innerController = friendRequestsController;
self.title = #"Requests";
break;
}
[innerController viewWillAppear:NO];
[innerView addSubview:innerController.view];
[innerController viewDidAppear:NO];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[innerController viewWillAppear:animated];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.navigationController.navigationBar.tintColor = nil;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[innerController viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[innerController viewWillDisappear:animated];
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[innerController viewDidDisappear:animated];
[super viewDidDisappear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[friendsController release], friendsController = nil;
[friendRequestsController release], friendRequestsController = nil;
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end
So can someone please tell me what's going on? HELP!
You need to set wantsFullScreenLayout property to YES.
in your init methods set
self.wantsFullScreenLayout = YES;
This will solve your problem.