Unexpected nil window with XCode 6 Universal application - iphone

I converted a working app to be Universal. However after overcoming most problems I am stuck with the following error when I run the app:
2015-01-16 13:51:20.663 CREW-Universal[820:13935] unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIClassicWindow: 0x7fc488c4be80; frame = (0 0; 375 667); userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x7fc488d3ae60>; layer = <UIWindowLayer: 0x7fc488c4c750>>
This error occurs when I click on the black window (in the simulator) which displays after the launch image appears.
An anyone suggest how I can find out the cause of this problem? (There is no script attached to the initial window.)

self.window = [UIWindow new];
[self.window makeKeyAndVisible];
self.window.frame = [[UIScreen mainScreen] bounds];
try this

Related

google admob not clickable inside rectangle

I'm making one app in phone-gap so I've to deal in web-views only. In this app I need to put ads in the bottom of the screen. I'm using google admob for this. This generates floating ad window. I've put this window in bottom of the screen but problem is my webview content is hiding behind this window.
So, I've make one rectangle and add this google admob window in this rectangle. It solved my data hiding problem, but now it is not click able.
My code:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
theWebView.backgroundColor = [UIColor blackColor];
CGRect viewBounds = CGRectMake([[UIScreen mainScreen] applicationFrame].origin.x, [[UIScreen mainScreen] applicationFrame].origin.y, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height-CGSizeFromGADAdSize(kGADAdSizeBanner).height);
self.view.frame = viewBounds;
CGPoint origin = CGPointMake(0.0,theWebView.frame.size.height);
bannerView_ = [[[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner origin:origin] autorelease];
bannerView_.adUnitID = #"___ADMOBID___";
bannerView_.rootViewController = self;
[self.view addSubview:bannerView_];
[bannerView_ loadRequest:[GADRequest request]];
return [super webViewDidFinishLoad:theWebView];
}
How to make admob clickable inside rectangle (CGRect)???
Thanks in advance...
You're actually making the main view smaller, which basically - I guess - rescales its contents (including the webview Then you're placing the banner view right under the webview, but it'll show up anyways as you most probably have the clipsToBounds flag set to NO in your main view.
What you need to do is to make the webview (not the main view) smaller using CGRectGetHeight(self.view.bounds) - CGRectGetHeight(kGADAdSizeBanner) (and not the application frame) and then lay them both out accordingly.
Check the self.view.clipsToBounds flag and set it to YES whether in code or in IB in order to test correct behaviour, what you don't see in screen won't get any touches.

Is it possible to put an image overlay over an entire iOS app?

I'd like to have a spotlight effect PNG image on top of my entire app. Even when the keyboard pops up.
Is this possible?
Add the PNG to a new window that overlays everything else:
UIWindow *totalOverlayWindow = [[UIWindow alloc] init];
totalOverlayWindow.frame = [[UIScreen mainScreen] bounds];
totalOverlayWindow.userInteractionEnabled = NO;
totalOverlayWindow.windowLevel = UIWindowLevelStatusBar + 1;
[totalOverlayWindow makeKeyAndVisible];
This window will now be above everything else.

iOS: addConstraints: crashing app

Problem
I can't seem to adopt Auto Layout into my existing project.
Details
I was having the same issue before as this question presentViewController: crash on iOS <6 (AutoLayout) but none of the provided answers were a solution for me: I'm using all storyboard views with no xibs. My 'Use Auto Layout' setting is already turned off and I am using nothing but iOS 6.
My view controller was initially crashing, so I set the constraints to be added with a delay and now my app crashes during any addConstraints: call. Worst part is that it won't tell me why.
Code
I will link my code, but its pretty straight forward.
-(void)addAllConstraints
{
NSDictionary * views = NSDictionaryOfVariableBindings(_memoryImage, _peopleView, _contentHolder, _commentsTableView);
NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[_memoryImage]-50-[_peopleView]-0-[_contentHolder]-0-[_commentsTableView]" options:0 metrics:nil views:views];
NSLog(#"Views %#, Constraints %#", views, constraints);
[_peopleView addConstraints:constraints];
[_memoryImage addConstraints:constraints];
[_contentHolder addConstraints:constraints];
[_commentsTableView addConstraints:constraints];
}
App crashes on _peopleView's call to addConstraints. Both the views and the NSLayoutConstraints are successfully created.
Any ideas? Thank you, Happy Holidays.
EDIT:
Adding Crash logs to show that nothing useful is showing:
2012-12-25 10:40:13.936 -----[4955:907] Views {
"_commentsTableView" = "<UITableView: 0x1eb6be00; frame = (0 372; 320 100); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1e51ce00>; layer = <CALayer: 0x1e51cee0>; contentOffset: {0, 0}>";
"_contentHolder" = "<UIView: 0x1e5c6590; frame = (0 270; 320 112); layer = <CALayer: 0x1e5c27f0>>";
"_memoryImage" = "<UIButton: 0x1e5c4aa0; frame = (0 0; 320 280); opaque = NO; layer = <CALayer: 0x1e5c4b60>>";
"_peopleView" = "<UIView: 0x1f0ceea0; frame = (0 230; 320 50); layer = <CALayer: 0x1f0cf790>>";
Constraints (
"NSLayoutConstraint:0x1e51a880 V:[UIButton:0x1e5c4aa0]-(50)-[UIView:0x1f0ceea0]",
"NSLayoutConstraint:0x1e5ba4e0 V:[UIView:0x1f0ceea0]-(0)-[UIView:0x1e5c6590]",
"NSLayoutConstraint:0x1e51b860 V:[UIView:0x1e5c6590]-(0)-[UITableView:0x1eb6be00]"
)
}
(lldb)
Constraints are supposed to be added to the view that is the superview of the subviews. So, if these objects are in your main view, then you should have (and none of the other addConstraints: lines):
[self.view addConstraints:constraints];
Also, your dictionary, views, should be nil terminated (I don't know whether this is necessary or not. I've noticed in an Apple example that they didn't do this, but the function definition shows it with the nil).

Fade out Launch Image on 4 Inch iPhone screen

On launch, I am fading from my launch image to the application's interface. To achieve this, I am adding a UIImageView with "Default.png" and animating its alpha just before makeKeyAndVisible.
Should Default.png always return the device-specific (or resolution-specific) version of the launch image? Or should I be checking the screen's bounds and scale to pick the right one for the retina vs non-retina and 3.5 vs 4 inch screens?
I expected Default.png to behave much like other image resources - use the #2x version when supported (and the -568h version on the iPhone 5). But my experimentation in the simulator leads me to believe otherwise. Running the 4 inch simulator, the 3.5 inch image is used. This results in a splash image that does not extend to the bottom of the screen. The screenshot below shows the transition mid-animation.
Unfortunately I don't have each device so was unable to confirm if this is just a quirk of the simulator.
In short, I want to be sure that the retina image is used on retina devices, and the 4 inch image is used on 4 inch devices.
This is my code
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self.window makeKeyAndVisible];
[self _startLaunchAnimation];
return YES;
}
- (void)_launchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
UIImageView *launchImageView = (UIImageView*)[self.window viewWithTag:1000];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone
forView:self.window
cache:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(startupAnimationDone:finished:context:)];
[launchImageView setAlpha:0.0];
[launchImageView setFrame:CGRectMake(-60.0f, 0.0f, 320.0f, screenHeight)];
[UIView commitAnimations];
}
- (void)_startLaunchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
NSString *imageName = nil;
if (screenHeight == 568.0f) {
imageName = #"Default-568h.png";
} else {
imageName = #"Default.png";
}
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *launchImageView = [[UIImageView alloc] initWithImage:image];
[launchImageView setTag:1000];
[self.window addSubview:launchImageView];
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(_launchAnimation)
userInfo:nil
repeats:NO];
}
For the record, this is my version of #agassi_yzh's solution:
//fade from the launch image to the interface
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
NSString *imageFile = (screenHeight == 568.0f) ? #"Default-568h.png" : #"Default.png";
UIImageView *splash = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageFile]];
[self.window.rootViewController.view addSubview:splash];
[UIView animateWithDuration:0.5
animations:^{
splash.alpha = 0;
}
completion:^(BOOL finished) {
[splash removeFromSuperview];
}
];
//display the main window
[self.window makeKeyAndVisible];
The answer is you will have to explicitly load the device specific version of the image. This is custom animation and you cannot rely on Apple's Default whatever loading behavior to achieve what you want.
First make sure that you you are configured properly and the correct default load image is displayed on the devices (dont trust the simulator too much (aka I never even use the simulator its so buggy))
And then as previous commenters suggested load a view with your images.
Remember that the default image is going to be loaded and shown by the cocoa framework. All you can do is show a view afterward, if you try and do some of the admittedly clever hacks with the on load that are on the web you will find that they will always break in some way.
If you need a full screen image animated or not on iPhone 5 you need to load that image explicitly for the device thats all there is to it.
Yes, you provide Default.png and Default#2x.png, you even have to supply Default-568h#2x.png for the iPhone 5 4" screen.
You app will use standard, retina or big retina according to device but note that Apple discourage using the Default launch image as any intro animation sequence.
The trick you could use is to add an image view as the first screen of the app when it's launched and immediately fade it out, this will give the user the impression that the launch image is fading out even though the launch image is gone, and it's your image view taking over.
Look at the Launch image section of the Apple Custom Icon and Image Creation Guidelines:
Supply a launch image to improve user experience.
Avoid using your launch image as an opportunity to provide:
• An “app entry experience,” such as a splash screen
• An About window
• Branding elements, unless they are a static part of your app’s first
screen Because users are likely to switch among apps frequently, you
should make every effort to cut launch time to a minimum, and you
should design a launch image that downplays the experience rather than
drawing attention to it.

UIScreen applicationFrame returning incorrect rectangle on landscape application launch (iPhone/iPad)

Having trouble getting the correct bounds for my iPad application when launching it in landscape mode. I have the proper keys set in my Info.plist file, and my view controllers launch properly in landscape (and portrait, natch).
In my applicationDidFinishLaunching: method I'm calling a selector after a 3 second delay, and that method makes a call to [[UIScreen mainScreen] applicationFrame], but it's returning me a portrait frame (ie height > width).
Does anyone know how to fix this? It smells like a bug to me (if so I'll file a radar), but if it's intended behaviour, where is it documented?
I never rely on [[UIScreen mainScreen] applicationFrame], especially during app launch.
When creating views in code, use the superview to set your frame.
If you're using xibs with "simulated interface elements" they will be correctly sized and everything will work great.
UINavigationController based apps
In the case of a UINavigationController based app, grab the frame directly from self.navigationController.view, don't try to use [self loadView] and self.view.superview. UINavigationController uses "hidden" subviews to do it's job--so the direct superview will not work.
UINavigationController is special because during app launch, the navigation controller resizes your views after loadView gets called. When autoresizing kicks in you end up with a small margin at the bottom of the screen.
Why not UIScreen
[[UIScreen mainScreen] applicationFrame] doesn't work reliably (especially during app launch in landscape). My experience is that the viewcontroller's interfaceOrientation property will not match the applicationFrame orientation.
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
When you are holding the iPad in landscape orientation and launch an app, the view controller initially sees bounds for a portrait view (even though orientation reports landscape). The view controller will then get a message to rotate to landscape orientation before it appears.
This is the way I get the correct CGRect when the view controller is on landscape:
CGRect landscapeBounds;
if (self.view.frame.size.width < self.view.frame.size.height)
landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width);
else
landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
This is as designed. You should query the size of your superview and adjust as necessary.
[[UIScreen mainScreen] applicationFrame] will always return the portrait rectangle even if the app is in landscape mode. This is related to the fact that UIWindow never actually rotates, but just changes the transform of rootViewController.view instead.
To make sure, you can print the root view object in portrait and landscape modes, and you'll see something like this:
Portrait:
<UIView: 0x96290e0; frame = (0 20; 768 1004); ...
Landscape:
<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
So, add a launch image and give it the suffix -568h, according to Apple's guides.
I don't understand why anyone with a sound mind would make a system setting depend on a graphic; but I just tested and it worked.
Here is the spot that taught me after a quick search I didn't see this answer above, figured it'd be useful to someone.
S
I got into same problem when dismissing view with dismissViewControllerAnimated in Cordova plugin.
I modified singingAtom code for viewWillAppear method in MainViewController, which got resized after dismissing modal view:
- (void)viewWillAppear:(BOOL)animated
{
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIDeviceOrientationLandscapeLeft == orientation ||
UIDeviceOrientationLandscapeRight == orientation)
{
if (appFrame.size.width < appFrame.size.height)
{
appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
}
}
self.view.frame = appFrame;
[super viewWillAppear:animated];
}