I'm trying to get a MoPub banner ad to appear. I've created a UIViewController, and put the MoPub code into the View did load as thus..
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// ... your other -viewDidLoad code ...
self.adView = [[MPAdView alloc] initWithAdUnitId:#"ID HERE"
size:MOPUB_BANNER_SIZE];
self.adView.delegate = self;
CGRect frame = self.adView.frame;
CGSize size = [self.adView adContentViewSize];
frame.origin.y = [[UIScreen mainScreen] applicationFrame].size.height - size.height;
self.adView.frame = frame;
[self.view addSubview:self.adView];
[self.adView loadAd];
//[super viewDidLoad];
}
#pragma mark - <MPAdViewDelegate>
- (UIViewController *)viewControllerForPresentingModalView {
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
And in my AppDelegate I'm setting everything up like this (it's a Sparrow game)
//setup Sparrow
CGRect screenBounds = [UIScreen mainScreen].bounds;
_window = [[UIWindow alloc] initWithFrame:screenBounds];
_gcViewController = [[UIViewController alloc]init];
_viewController = [[SPViewController alloc] init];
[_viewController startWithRoot:[Game class] supportHighResolutions:YES doubleOnPad:YES];
_viewController.multitouchEnabled = YES;
[_window setRootViewController:_viewController];
adViewController = [[AdViewController alloc]init];
[_window addSubview:adViewController.view];
[_window addSubview:_gcViewController.view];
[_window makeKeyAndVisible];
And in the console I seem to be getting the correct msgs as this...
Looking for custom event class named MPHTMLBannerCustomEvent. MOPUB:
Loading MoPub HTML banner MOPUB: MoPub HTML banner did load
But I can't see anything on the screen in the simulator, any ideas?
Related
Edit: Here's my AppDelegate as well (part of it)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
_bannerViewController = [[BannerViewController alloc]initWithContentViewController:gameViewController];
self.window.rootViewController = _bannerViewController;
[self.window makeKeyAndVisible];
return YES;
}
I am about to give up. I have tried 5 different ways just these past few days to get literally one single iAd to show correctly and as simple as Apple makes it seem, literally 100% of the time I either see no ad or get an error. I have followed the Apple documentation EXACTLY.
The only clue I have is in these two lines
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
Which are in my app delegate. The NSLog gives me "UIView". No. Why? Why would that ever be a UIView, it should be an SKView, because GameViewController was pre-written for me by apple for sprite kit. How could that possibly give me the wrong object?
I am getting 'NSInvalidArgumentException', reason: '-[UIView scene]: unrecognized selector sent to instance 0x174191780' which others have recommended to fix by putting the originalContent statement but I already have that and it isn't working.
Banner view controller:
#import "BannerViewController.h"
NSString * const BannerViewActionWillBegin = #"BannerViewActionWillBegin";
NSString * const BannerViewActionDidFinish = #"BannerViewActionDidFinish";
#interface BannerViewController () <ADBannerViewDelegate>
#end
#implementation BannerViewController {
ADBannerView *_bannerView;
UIViewController *_contentController;
}
-(instancetype)initWithContentViewController:(UIViewController *)contentController{
NSAssert(contentController != nil, #"Attempting to initialize a BannerViewController with a nil contentController.");
self = [super init];
if (self != nil) {
_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_contentController = contentController;
_bannerView.delegate = self;
}
return self;
}
-(void)loadView{
UIView *contentView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
//Have also tried SKView *contentView = [[SKView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
[contentView addSubview:_bannerView];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
self.view = contentView;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [_contentController preferredInterfaceOrientationForPresentation];
}
-(NSUInteger)supportedInterfaceOrientations{
return [_contentController supportedInterfaceOrientations];
}
-(void)viewDidLayoutSubviews{
CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero;
bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
if(_bannerView.bannerLoaded){
contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.size.height;
}else{
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionWillBegin object:self];
return YES;
}
-(void)bannerViewActionDidFinish:(ADBannerView *)banner{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionDidFinish object:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Game View controller:
#interface GameViewController ()
#property (nonatomic, strong) IBOutlet UIView *contentView;
#end
#implementation GameViewController {
}
-(instancetype)init{
self = [super init];
if (self) {
}
return self;
}
-(void)viewDidLoad{
//self.canDisplayBannerAds = YES;
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
-(void)viewDidLayoutSubviews{
}
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
SKView *skView = (SKView*)self.originalContentView;
if (!skView.scene) {
SKScene *scene = [GameScene sceneWithSize:skView.bounds.size];
[skView presentScene:scene];
//skView.showsPhysics = YES;
}
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskPortrait;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
I figured it out. The answer, as I thought it would be, was incredibly simple and quite mind-boggling that Apple wouldn't put some sort of warning in their documentation, but then again maybe I am just too much of a noob and we are expected to know these kinds of things.
The answer, is that init was never being called in GameViewController, instead, initWithCoder: was being called. Once I NSLogged the init method and saw it wasn't being called, I figured this out.
I'm trying to animate a custom property, and as I've seen on several sources it seems this would be the way to go, but I'm missing something. Here's the CALayer subclass:
#implementation HyNavigationLineLayer
#dynamic offset;
- (instancetype)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self) {
HyNavigationLineLayer * other = (HyNavigationLineLayer*)layer;
self.offset = other.offset;
}
return self;
}
-(CABasicAnimation *)makeAnimationForKey:(NSString *)key
{
// TODO
return nil;
}
- (id<CAAction>)actionForKey:(NSString *)event
{
if ([event isEqualToString:#"offset"]) {
return [self makeAnimationForKey:event];
}
return [super actionForKey:event];
}
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:#"offset"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
- (void)drawInContext:(CGContextRef)ctx
{
NSLog(#"Never gets called");
}
#end
I believe this is the only relevant method on my view:
#implementation HyNavigationLineView
+ (Class)layerClass
{
return [HyNavigationLineLayer class];
}
#end
And, finally, in my view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Instantiate the navigation line view
CGRect navLineFrame = CGRectMake(0.0f, 120.0f, self.view.frame.size.width, 15.0f);
self.navigationLineView = [[HyNavigationLineView alloc] initWithFrame:navLineFrame];
// Make it's background transparent
self.navigationLineView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
self.navigationLineView.opaque = NO;
[[self.navigationLineView layer] addSublayer:[[HyNavigationLineLayer alloc] init]];
[self.view addSubview:self.navigationLineView];
}
The thing is that the drawInContext method is not called at all, although layerClass is. Am I missing something to make the layer draw?
Solved it. Need to call setNeedsDisplay
- (void)viewDidLoad
{
[super viewDidLoad];
// Instantiate the navigation line view
CGRect navLineFrame = CGRectMake(0.0f, 120.0f, self.view.frame.size.width, 15.0f);
self.navigationLineView = [[HyNavigationLineView alloc] initWithFrame:navLineFrame];
// Make it's background transparent
self.navigationLineView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
self.navigationLineView.opaque = NO;
[[self.navigationLineView layer] addSublayer:[[HyNavigationLineLayer alloc] init]];
[self.view addSubview:self.navigationLineView];
[self.navigationLineView.layer setNeedsDisplay];
}
I have created a simple hello world project for cocos2d-x 3.2. Added AdMob banner. The essence of adding banner is to create a view, then add into that view first the cocos2d-x content and then banner content:
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
[contentView addSubview:_bannerView];
self.view = contentView;
The result is that on iPhone, iPhone Retina, iPad Retina (but not in iPad) the Hello World text is distorted like this:
At the same time that stats text is not distorted:
I cannot understand what happens and why. Here is my full code:
.hfile
#import <UIKit/UIKit.h>
#interface BannerViewController : UIViewController
- (instancetype)initWithContentViewController:(UIViewController *)contentController;
- (void) hideBanner;
- (void) showBanner;
#end
and hers is .mm file
#import "BannerViewController.h"
#import "GADBannerView.h"
#interface BannerViewController () <GADBannerViewDelegate>
#end
#implementation BannerViewController {
GADBannerView *_bannerView;
UIViewController *_contentController;
Boolean _bannerLoaded;
}
- (instancetype)initWithContentViewController:(UIViewController *)contentController
{
self = [super init];
if (self != nil) {
// use kGADAdSizeBanner for a small banner in iPad
_bannerView = [[GADBannerView alloc] initWithAdSize: kGADAdSizeSmartBannerPortrait]; // scaled banner dependent on device size
_bannerView.adUnitID = #"ca-app-pub-874958723945898/8247587858";
_bannerView.delegate = self;
_contentController = contentController;
_bannerLoaded = NO;
}
return self;
}
- (void)loadView
{
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
[contentView addSubview:_bannerView];
self.view = contentView;
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
#endif
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [_contentController preferredInterfaceOrientationForPresentation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [_contentController supportedInterfaceOrientations];
}
// For animation
- (void)viewDidLayoutSubviews
{
CGRect contentFrame = self.view.bounds;
CGRect bannerFrame = CGRectZero;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
bannerFrame = _bannerView.frame;
#else
bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
#endif
bannerFrame.origin.x = (contentFrame.size.width - bannerFrame.size.width) / 2;
if (_bannerLoaded) {
//contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.size.height - bannerFrame.size.height;
} else {
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
- (void)viewDidLoad {
[super viewDidLoad];
_bannerView.rootViewController = self;
[self.view addSubview:_bannerView];
GADRequest *request = [GADRequest request];
[_bannerView loadRequest:request];
}
- (void)adViewDidReceiveAd:(GADBannerView *)bannerView
{
NSLog(#"adViewDidReceiveAd");
_bannerLoaded = YES;
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error
{
NSLog(#"adView didFailToReceiveAdWithError");
_bannerLoaded = NO;
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void) hideBanner{
//TODO:
}
- (void) showBanner{
//TODO:
}
- (void)dealloc {
_bannerView.delegate = nil;
[_bannerView release];
[super dealloc];
}
#end
// </GADBannerViewDelegate>
And I use it in AppController.mm like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
// Init the CCEAGLView
CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
depthFormat: GL_DEPTH24_STENCIL8_OES
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples: 0];
// Use RootViewController manage CCEAGLView
_viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
_viewController.wantsFullScreenLayout = YES;
_viewController.view = eaglView;
_bannerViewController = [[BannerViewController alloc] initWithContentViewController:_viewController];
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: _bannerViewController.view];
//[window addSubview: _viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:_bannerViewController];
// [window setRootViewController:_viewController];
}
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden:true];
// IMPORTANT: Setting the GLView should be done after creating the RootViewController
cocos2d::GLView *glview = cocos2d::GLView::createWithEAGLView(eaglView);
cocos2d::Director::getInstance()->setOpenGLView(glview);
cocos2d::Application::getInstance()->run();
return YES;
}
What is wrong here?
I have found the problem. I appears that there is a time in hours written with black color like in the image, which on on the Hello World label and hence it distorts:
The time is shown is simulators status bar. In order to hide it I added this:
//fix not hide status on ios7
- (BOOL)prefersStatusBarHidden
{
return YES;
}
into BannerViewController class and that's it!
when I click the popover button in my splitviewcontroller, I receive the message: message sent to deallocated instance 0x6a66ca0
I already found out that this instance has to be the detailviewcontroller I allocate and init. So far so good. But I don't see the problem while the whole thing is not working.
First of all the AppDelegate where I create the Splitview:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// TestViews for SplitViewController
// TestView1 *test1 = [[TestView1 alloc] initWithNibName:#"TestView1" bundle:nil];
// TableView as RootViewController for the Left Hand Pane
RootViewTableViewController *rootViewTableViewController = [[RootViewTableViewController alloc] initWithNibName:#"RootViewTableView" bundle:nil];
UINavigationController *rootNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewTableViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:rootNavigationController,detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
return YES;
}
First I was thinking the code line self.splitviewcontroller.delegate = detailviewcontroller; could be the problem..... but the whole app starts up perfectly. only when i click the button this prob appears.
the RootViewController is this ( I omitted the standard tableview delegate methods for clarity)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Set Title of the TableView for the RootViewController
self.title = #"Notarzteinsatzprotokoll";
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
}
NSLog(#"INIT %p", self);
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
and the detail view controller:
#pragma mark -
#pragma mark Managing the Detail Item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view
[self configureView];
}
if (self.rootPopoverController != nil) {
[self.rootPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setTitle:#"Notarzteinsatzprotokoll"];
[self configureView];
}
#pragma mark -
#pragma mark Rotation Support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
#pragma mark -
#pragma mark SplitView
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc {
barButtonItem.title = #"Master";
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
self.rootPopoverController = pc;
}
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
self.rootPopoverController = nil;
}
I don't see the point the program flow where the detailviewcontroller objects is released and something else tries to send a message... do I have to interchange some code lines?
Thank you!
Sebastian
#end
the error should tell you what message is being sent to a deallocated instance. Not sure exactly what the issue is, is it a setTitle: message being sent to the left bar button item?
In splitViewController:willShowViewController: you set the left bar button item to nil (which will dealloc it) and in splitViewController:willHideViewController: you attempt to changed its title, which could be your problem.
I want to package some UIViews suchs as UIButton, UIImageView in a single UIView.
When I try to display that view, it is not showing up on my RootViewController:
Here is the code of my UIView subclass :
#import "Hover.h"
#implementation Hover
- (id)init{
self = [super init];
if (self) {
// Initialization code
UIImage *hover = [UIImage imageNamed:#"Hover.png"];
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = hover;
imageView.frame = CGRectMake(0, 0, hover.size.width, hover.size.height);
imageView.alpha = 0.75;
[self addSubview:imageView];
[imageView release];
}
return self;
}
And here is the RootViewController class:
- (void)viewDidLoad
{
Hover *hover = [[Hover alloc] init];
[self.navigationController.view addSubview:hover];
[hover release];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
The "hover view" is not displayed! However, when I add a single UIImageView to my RootViewController, it works!
In order for your view to display, you should override the -(id)initWithFrame:(CGRect)frame;, instead of writing a custom initializer.
Try this way :
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self) {
// do init here...
}
return self;
}
Also, in the -(void)viewDidLoad; method, first send [super viewDidLoad];, and then alloc/init the view.
- (void)viewDidLoad
{
[super viewDidLoad];
Hover *hover = [[Hover alloc] init];
[self.navigationController.visibleViewController.view addSubview:hover];
[hover release];
// Do any additional setup after loading the view, typically from a nib.
}
Just a quick guess at a glance: If you're using a navigationcontroller, you should initWithRootViewController. You can't add a view to a navigationcontroller directly, Use push instead.
HTH
Marcus