MBProgrssHUD error with Cocos2d - objective-c

Here is the simple code of usage of MBProgressHUD
// Add at the top of the file
#import "MBProgressHUD.h"
// Add right before return TRUE in textFieldShouldReturn
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Redeeming code...";
// Add at start of requestFinished AND requestFailed
[MBProgressHUD hideHUDForView:self.view animated:YES];
And obviously we need a view to add the MBProgressHUD into.
The problem is that there is no view in cocos2d, but only CCNode.
So, is there any way to solve this problem?
By adding an UIview onto a CCLayer ?
If this is a stupid question, please accept my apology as I am still very new in programming.

adding an UIView onto a CCLayer cannot be done because they are separate view hierarchies'
you will need to find your toplevel EAGLView (which subclasses UIView) and add the MBProgressHUD as a child of that. Or use a cocos2d menu system.
Or you could port the MBProgressHUD code into cocos2d?

Related

Spritekit iAds messing with scene size

I am making a game using spritekit and everything works perfectly except when I add the code to add an iAd. When I add the iAd everything works but it seems that the iAd is resizing the scene when it is being displayed.
This is my code to display the iAd, it is in the ViewController.m :
#import <iAd/iAd.h>
#import "ViewController.h"
#import "MainMenu.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.originalContentView;
skView.showsFPS = YES;
// Create and configure the scene.
SKScene * scene = [MainMenu sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
self.canDisplayBannerAds = YES;
// Present the scene.
[skView presentScene:scene];
}
Like I say, the iAd shows up, and all the function properly but the when the iAd is displayed it makes the scene smaller, is there a method or something that allows the scenes to not be resized?
An help is much appreciated, thanks!
Ok so I sort of figured it out, I was using scaleMode of SKSceneScaleModeAspectFit I have now changed it to SKSceneScaleModeFill this seems to make the scene shorter but it is not as noticeable as the aspectFit scale mode. I have also noticed that the iAd does not act like a sprite as it actually distorts or resizes the screen. If anyone knows how to create the iAd on top of the view, like sprite, please add a comment or solution.
EDIT
I have just figured out that one can add an ADBannerView to the viewcontroller in the interface builder, this will show the ad on all scenes. I am now trying to figure out how this can be set to not display on specific scenes seeing spritekit only uses one viewcontroller.
If you add the ad by adding in the AdBannerView then you have to create seperate methods in the view controller to turn the ads on or off, by creating these seperate methods it allows one to have manual control over the ads in the view controller from any scene.
In the view controller you have a scene that you create, this scene variable/object has a property of tag or userdata. So if your game goes to a different scene you can call
[super scene] setTag:x]
Every time that the NSTimer calls my control method it checks the value of the scenes tag in the view controller and based on that value it will remove or re-display the ad.
Just a thought, but you could also put the AdBannerView in via the Storyboard editor, and then set
self.canDisplayBannerAds = NO;
That way it will just overlay the SKScene instead of shrinking it.
Hope this helps!
There is another way to fix this problem. You might want to have a look at this Thread.
iAd in Spritekit
Just a sneak preview:
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.delegate = self;
[adView setFrame:CGRectMake(0, 0, 1024, 768)]; // set to your screen dimensions
[adView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:adView];

EXC_BAD_ACCESS at removeFromSuperview - using ARC

In one of my ViewControllers (ViewController A), I have the following code:
AlertViewController *aViewController = [[AlertViewController alloc] initWithNibName:#"AlertViewController" bundle:nil];
[self.view addSubview:[aViewController view]];
[self.view bringSubviewToFront:[aViewController view]];
And in AlertViewController, I have a button and when the user clicks on it, I have:
[self.view removeFromSuperview];
Whenever I click the button, the result is EXC_BAD_ACCESS.
I'm unable to figure out the problem. My project is using ARC and ViewController A is part of a navigation controller stack if that info helps.
The problem here is that the UIView doesn't own its UIViewController. In the first block of code you held the UIView around by adding it to a subview, but let the UIViewController go away. The UIView from a UIViewController is special, you can't let this happen.
Make sure the UIViewController that created the UIView lives as long as the view does.

AppDelegate can't add subView

Since appDelegate does not have a view, just window, its hard to figure out how to load a view from it. My problem has for long been that when didReceiveLocalNotification fires i cant load a new view with that event. I have been working around it til the point that i must do something about it. When i tries to addSubview, xcode gives me the error:
Receiver tupe 'UIWindow' for instance messages does not declare a method with selector 'addSubView'
for this: (at [self.window addSubView:view];)
screwLightBulbViewController *view = [screwLightBulbViewController newMyView];
[self.window addSubView:view];
I understand that the appDelegate file does'nt have a addSubview but i want to switch to a particular view when it fires.
I have tried many other ways, like calling a function in screwLightBulbViewController and make a view from that. My function in the viewController now looks like this:
+(id)newMyView
{
UINib *nib = [UINib nibWithNibName:#"MyView" bundle:nil];
NSArray *nibArray = [nib instantiateWithOwner:self options:nil];
screwLightBulbViewController *me = [nibArray objectAtIndex: 0];
return me;
}
any help in any way would be realy appreciated and thanks for you time. :)
It's addSubview not addSubView:. UIWindow is a subclass of UIView.
Adding a view directly as a subview to the window is not usually recommended, so instead you should try and add the view as a subview to the top controller view. If you can spare some time you should look over the view programming guide and view controller programming guide, it will be useful in the future.

Is this a correct way to add/remove views?

Lets say that I have 4 view controllers (call them FirstView,SecondView,ThirdView,FourthView) which are created programmatically and all are in separate files:
In AppDelegate.m didFinishLaunchingWithOptions method I have these lines of code
self.rootViewController = [[rootViewController alloc]initWithNibName:#"rootViewController" bundle:nil];
self.window.rootViewController = self.rootViewController;
In rootViewController.m loadview method I have
self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.firstView = [[FirstView alloc]init];
[self.view addSubview:self.firstView.view];
That code works fine - first view is displayed.
Let's continue
In FirstView.m switchViews method
NOTE: Please see the comments in code
self.secondView = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
// I think here secondView is added to rootViewController - right ?
[self.view.superview addSubview:self.secondView.view];
// Here first view is removed from rootViewController - right ?
[self.view removeFromSuperview];
Here is how I add/remove views.
Is this approach correct?
Can you recommend a better solution?
I have read about UINavigationController, but I don't think it could be a solution in this case.
You say:
I have 4 views (call them FirstView ...
Then you say:
[self.view addSubview:self.firstView.view];
Which makes me think that FirstView isn't actually a UIView - as you claim it is. Instead, it's probably a UIViewController - a different beast altogether.
If my suspicion is correct - then you are "off-track" so to speak.
Going beyond that to your sample code snippet:
self.secondView = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
// I think here secondView is added to rootViewController - right ?
[self.view.superview addSubview:self.secondView.view];
// Here first view is removed from rootViewController - right ?
[self.view removeFromSuperview];
This is definitely not a great idea. Here's why:
First: your view controller doesn't explicitly "know" anything about the superview you are so casually inserting and removing subviews to/from - so it shouldn't do that. You may, alternatively, create your own view and insert/remove subviews from that - which would not only be perfectly acceptable but also common practice.
Second: if these are actually UIViewControllers like I think they are - then you are not properly handling hooking them up to the UIViewController event chain - which means methods on these subclasses like viewDidAppear: or viewDidUnload will not fire.
From what I see in your code, UINavigationController seems like it would help. If you don't want a navigation bar, you can definitely hide it, but the methods in UINavigationController should help you with switching views.
If your views only need to display temporarily, you could also use Modal View controllers. An example of Modal View controllers can be found here.
If you haven't already, check out the View Controller Programming Guide from Apple.

Trying to dismiss subview and UIView

I'm still very new to iOS developing. In fact, if there is a super noob, I would be one :p. Currently I am working on creating an IBAction button that accesses a subview. I have 2 ViewControllers, AddClientVC and NewClientVC, both with .nib files. So basically, inside my AddClientVC I implement an IBAction button with the following code:
- (IBAction)buttonPressed:(id)sender
{
UIView *transparentBG = [[UIView alloc] initWithFrame:CGRectMake(-5, -5, 1500, 2500)];
transparentBG.backgroundColor = [UIColor blackColor];
transparentBG.opaque = NO;
transparentBG.alpha = 0.5;
[self.view addSubview:transparentBG];
transparentBG.center = transparentBG.center;
vc = [[NewClientVC alloc] initWithNibName:#"NewClientVC" bundle:nil];
[self.view addSubview:vc.view];
vc.view.center = self.view.center;
}
As you can see I implemented a UIView as a transparent background. Basically AddClientVC --> Transparent Background --> NewClientVC. Now I have created another IBAction button but this time inside NewClientVC as a function to dismiss the accessed subview which looks like this:
- (IBAction)saveDismiss:(id)sender
{
[self.view removeFromSuperview];
}
The problem I'm having right now is when I click the saveDismiss button it only removes the subview that I called previously on AddClientVC but it didn't remove the transparent background I have created as a UIView. So the problem is how do I implement an action which simultaneously removes my subview and the UIView transparent background I created.
I need all the help I can get :)
I'm not too sure I fully understand what you want to happen, but maybe you could try something like this?
- (IBAction)saveDismiss:(id)sender
{
[vc removeFromSuperView];
[self.view removeFromSuperview];
}
I recommend not to manage your screens by adding subviews manually but instead use
- (void)presentModalViewController: (UIViewController *)modalViewController
animated: (BOOL)animated
method on your root viewController.
Or better instantiate a UINavigationController and use push and pop methods to drill down/up your views.
See apple reference here
Do not worry about code execution speed and stay confident in apple's SDK. UIKit is optimized for best user experience. Trying to boost your code by doing inappropriate SDK use is, in my opinion, a risky strategy. ;) – Vincent Zgueb
Sorry Vincent but I don't agree with you. I reached here because I want to implement an gesture that adds a sub-view for my view, which will be the navigation of my app.
[self.view addSubview:ctrl.view];
is faster presenting the view than
[self.navigationController presentModalViewController:ctrl animated:NO]
and by the way, the solution to the topic in my case was:
[self.view sendSubviewToBack:ctrl.view];