Spritekit iAds messing with scene size - objective-c

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];

Related

How can I enable iAd when using Sprite Kit?

In IOS 7, we can enable iAd very easy when using:
self.canDisplayBannerAds = YES;
in code ViewDidLoad of UIViewController
However, I cannot use this in my ViewController (the ViewControl that load SKScene). My game is crash when loading.
So how can I active iAd in my game (using Sprite Kit)?
You can only show iAd in a UIViewController subclass. You are doing it right. Put the following code in your UIViewController and not in the SKScene.
Please refer to this tutorial for the exact code: http://tutorials.veasoftware.com/2013/10/10/how-to-add-iads/
It's possible that you are accessing the view property. When using iAds you need to replace .view with .originalContentView. For example:
SKView* skView = (SKView *)self.view;
is replaced with
SKView* skView = (SKView *)self.originalContentView;

UIView inside a UIViewController or better way to do it?

I have a problem on how to properly do a certain kind of action.
The image below shows a UIViewController, but the second part of the view is a custom UIView (the one with the profile pic, name and Show View button).
The subclassed UIView is allocated using this code:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
[self.view addSubview:profileView];
The problem is of course, that the button on the UIView can't show any view, since it's only the UIViewController that can push another ViewController to the window(correct?).
The UIView is used in several places in the app and needs to be added easily and have the same behavior across the application.
This worked great until I added the button, and I'm starting to think I've made this wrong, and there has to be a better way to do it (maybe change the UIView to something else?).
I was thinking I should be able to call:
self.superview
And then somehow get the ViewController so I can push another ViewController into the view hierarchy, but nope.
Any suggestions and a tips on how to do this correctly?
UPDATE:
I have no idea on how to push another UIViewController from the button.
What should I do in this method when pressing the button in the UIView:
- (void) showViewButtonTouched:(UIButton*)sender {
GPProfileSocialFriendsViewController *friendsSettings = [[GPProfileSocialFriendsViewController alloc] init];
}
How do I push GPProfileSocialFriendsViewController?
Your - (void) showViewButtonTouched:(UIButton*)sender method should be in your controller and would probably be better named - (void) showView:(UIButton*)sender or - (void) showProfile:(UIButton*)sender so it clearly denotes what it does (not how you got there).
It's not the view's responsibility to manage transitions from a state to another. If you move your method to your controller, your problem is no more (you can easily access self.navigationController or push directly if you don't have an navigation controller like this:
[self presentViewController:vcThatNeedsToBePushed animated:YES completion:nil];
I think you can create weak reference in GPProfileView on UIViewController. Like this:
#property (weak, nonatomic) UIViewController *rootController;
when you create GPProfileView, assign rootController-property:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
profileView.rootController = self; // if view created in view controller
[self.view addSubview:profileView];
and in implementation of button selector:
self.rootController push... // or pop
May be this not correct, but you can try
You could let the view controller push the next view controller when the button is pushed. The view controller can add a target/action on the button, so that the action method in the view controller is called on the touch up inside event.

How do I speed up iOS transitions and segues?

Is it possible to set a property application-wide to double the speed of transitions within an iOS app?
Application-wide?
Try setting the speed property on the backing layer for your view controllers' content views. speed=2 would be double-speed. You could probably set this in the viewDidLoad method for all your view controllers.
You might also be able to create a custom subclass of UIWindow, and have that window object set the speed property on it's view layer to 2.0 in a bottleneck method like makeKeyWindow. You'd need to make all your app's UIWindow objects use your custom class. I'd have to do some digging to figure out how to do that.
##Edit:
Or, better idea, set self.window.layer.speed = 2.0 in your app delegate after creating the window, as suggested by #Costique in the comment below.
Note that this approach will speed up ALL animations, not just transitions and segues. If you only want to speed up segues you would have to figure out how to target just those animations. I'd have to think about that.
Apple does not have a simple way to change that since it would make transitions too heterogenous amongst different apps. You could double the layer's speed, but that would mess up the timing on the rest of your animations. The best way is to implement your own transition using a category on UIViewControler.
UIViewController+ShowModalFromView.h
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#interface UIViewController (ShowModalFromView)
- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view;
#end
UIViewController+ShowModalFromView.m
#import "UIViewController+ShowModalFromView.h"
#implementation UIViewController (ShowModalFromView)
- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view {
modalViewController.modalPresentationStyle = UIModalPresentationFormSheet;
// Add the modal viewController but don't animate it. We will handle the animation manually
[self presentModalViewController:modalViewController animated:NO];
// Remove the shadow. It causes weird artifacts while animating the view.
CGColorRef originalShadowColor = modalViewController.view.superview.layer.shadowColor;
modalViewController.view.superview.layer.shadowColor = [[UIColor clearColor] CGColor];
// Save the original size of the viewController's view
CGRect originalFrame = modalViewController.view.superview.frame;
// Set the frame to the one of the view we want to animate from
modalViewController.view.superview.frame = view.frame;
// Begin animation
[UIView animateWithDuration:1.0f
animations:^{
// Set the original frame back
modalViewController.view.superview.frame = originalFrame;
}
completion:^(BOOL finished) {
// Set the original shadow color back after the animation has finished
modalViewController.view.superview.layer.shadowColor = originalShadowColor;
}];
}
#end
This can easily be changed to use whatever animated transition you want. Hope this helps!

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];

Draggable/tabbable UIPopOverController?

I don't know if you people are familiar with the Blackboard Learn app for iPad. Well it has PopUp windows to show info.
Well, I would like to implement something similar on a iPad app, and I was wondering if it is possible to doit with UIPopOverControllers...
Basically you can open a view and drag it around and keep it on a border of the screen as a tab to show updates and so.
Is it possible to do something similar with UIPopOverControllers or UIViews (the dragging and the tabbing)?
Cheers from Mexico
UPDATE 1:
Well, I managed to load multiple UIViews, next thing goes to be able to drag 'em around, any suggestions?
UPDATE 2:
I tried to add the UIPanGestureRecognizer in otherView.m (the Pop Up Window), here's how it looks
otherView.h
#interface otherView : UIViewController <UIGestureRecognizerDelegate>{
UIPanGestureRecognizer *drag;
}
#property (nonatomic, retain) UIPanGestureRecognizer *drag;
...
otherView.m
- (void)viewDidLoad {
[super viewDidLoad];
// Drag
drag = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(dragAction)];
[self.view addGestureRecognizer:drag];
[drag release];
}
otherView is displayed in mainWindow directly from the appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch.
// Set the view controller as the window's root view controller and display.
//self.window.rootViewController = self.viewController;
[window addSubview:viewController.view];
[window addSubview:secondView.view];
[self.window makeKeyAndVisible];
return YES;
}
Hope you can help me out
As far as I know there is no mechanism to move a popover around on the screen - they are attached to a bar button or point in a view and that is where they exist until they are dismissed. Popovers also don't allow interaction with views (buttons, text fields etc) in the main view while they are visible.
Sounds like a great user interface concept though, good luck!!