Status bar rotates separated from UIWindow - objective-c

I have to create application with two UIWindow (please, don't ask why). First UIWindow's rootViewController supports all orientations. Second one - only portrait and upside down. So application delegate code looks like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// part one
self.windowOne = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.windowOne.rootViewController = [[ViewControllerOne alloc] init]; // supports all orientations
self.windowOne.rootViewController.view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.png"]] autorelease];
[self.windowOne makeKeyAndVisible];
//~part one
// part two
self.windowTwo = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.windowTwo.rootViewController = [[ViewControllerTwo alloc] init]; // supports only portrait and upside down
self.windowTwo.rootViewController.view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image2.png"]] autorelease];
[self.windowTwo makeKeyAndVisible];
//~part two
return YES;
}
If only one of two parts is active (second one is commented) - everything is ok. But if windowOne has become key and visible before windowTwo, windowTwo rotates as ViewControllerTwo allows, but status bar behaves really weird: it rotates like windowOne is key and visible.
Is there any option to make status bar rotating as ViewControllerTwo says?

Albeit its a hack to me but what you could try is the following:
In your view controllers shouldAutorotateToInterfaceOrientation (for iOS5) or shouldAutorotate (as for iOS6) method add the following code line:
[[UIApplication sharedApplication] setStatusBarOrientation: interfaceOrientation animated: YES];
and test out how the app behaves after that.
to get the interface-orientation in the (new for iOS6) shouldAutorotate method do the following:
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
I didn't test this all out for myself, but it could work.
(Check out some post on how to support autorotation under iOS6)

Related

Objective C Navigation Bar does not adjust when StatusBar changes

We have a problem where the user is using our app on the iPhone and receives a call while on a view that has been presented by the rootviewcontroller and is covering the navigation controller and it's nav bar. The status bar for the call shows and pushes the current view down but when that view is removed from the superview, the status bar covers half of the navigation bar.
We have tried using a UIApplicationWillChangeStatusBarFrameNotification in the app delegate and then adjusting the size of the navigation controller and the navigation bar to no effect. We have also tried resetting the frame of the navigation controller and nav bar in the viewWillAppear function of the page that presents the view.
Can anyone tell us where we are going wrong?
In App Delegate we tried this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setupAppStyles];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor ugBlue];
UINavigationController *navController = [[UINavigationController alloc] init];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
[self setUpNotifications];
return YES; }
-(void) setUpNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(statusFrameChanged:)
name:UIApplicationWillChangeStatusBarFrameNotification
object:nil];}
- (void)statusFrameChanged:(NSNotification*)note {
CGRect statusBarFrame = [note.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue];
self.statusHeight = statusBarFrame.size.height;
UIScreen *screen = [UIScreen mainScreen];
CGRect viewRect = screen.bounds;
viewRect.size.height -= self.statusHeight;
viewRect.origin.y += self.statusHeight;
[[UINavigationBar appearance] setFrame:viewRect];
NSLog(#"The status frame has changed");
//[self.navController.view setFrame:viewRect];
self.navController.view.frame.size.height);}
We have also tried something similar in the views viewWillAppear functions also with no positive results. Any thoughts?
We were able to solve this problem. In the viewDidAppear of the view that called presentViewController we put
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGRect frame = CGRectMake(0.0f, statusSize, screenRect.size.width, navBarHeight);
[self.navigationController.navigationBar setFrame:frame];
When the status bar is shown

Modifying UINavigation controller programatically in Xcode5

I have a programmatically generated UINavigationController applied to each of my ViewControllers but this UINavigationController is blank. I need to add some text, an image (if possible) and two buttons.
I have managed to do something similar with a very basic app that only has one ViewController and UINavigationController created in the normal manner but do not know what to do in regards to a programmatically generated one.
I am using storyboards in XCode5/iOS7.
Here is the code that generates the UINavigationController and launches the first ViewController:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
MainViewController* mainVC = [mainStoryboard instantiateInitialViewController];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:mainVC];
[self.window setRootViewController:navVC];
[_window makeKeyAndVisible];
return YES;
}
I have tried things that I thought would be obvious like:
navVC.navigationBar.backgroundColor = [UIColor redColor];
To change the colour or:
[navVC setTitle:#"Test title"];
But nothing changes, the only way I could get the title to change was to change the title of mainVC
[mainVC setTitle:#"Test title"];
Changing the title in the MainViewController.m file itself does nothing.
So how do I modify the UINavigationController (navVC)?
Thanks,
You should be able to set an image to your navigation bar in this way:
UINavigationBar *navBar = navVC.navigationBar;
UIImage *image = [UIImage imageNamed:#"YourNavBarImg.png"];
[navBar setBackgroundImage:image];
and this to change the nav bar tint color:
[navVC.navigationBar setTranslucent:NO];
[navVC.navigationBar setBarTintColor:[UIColor redColor]];
about buttons (UIBarButtonItem) into nav bar:
// where "self" is your current viewcontroller
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:button1,button2, nil];

Second UIScreen causing problems with UIStoryboards

In my app delegate i set up another screen (for airPlay).
When i create a second window and assign the Second screen to it and run the app the TableView in my storyboard turns to a black colour. Its as if the tableView is not rendering correctly. I have isolated the problem to :
self.HDTVwindow.screen=[[UIScreen screens] objectAtIndex:1];
where the HDTVWindow is the second window for my airplay app. When i comment out this code the storyboard runs fine and my UITableView is nice and white. Am i confusing the storyboard by making two UIWindows in the appDelegate, even though they are assigned to different screens??
For my appDelegate see below.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[UIScreen screens] count]>1)
{
CGRect frame = [[UIScreen screens]objectAtIndex:1].bounds;
self.HDTVwindow = [[UIWindow alloc] initWithFrame:frame];
UIImage* astonLogo=[UIImage imageNamed:#"AstonUni720p.png"];
UIImageView* astonLogoView=[[UIImageView alloc] initWithImage:astonLogo];
astonLogoView.frame=frame;
[self.HDTVwindow addSubview:astonLogoView];
self.HDTVwindow.hidden = NO;
self.HDTVwindow.screen=[[UIScreen screens] objectAtIndex:1];//PROBLEM!!
}
// Set Up Storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *mainViewController = [storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
The problem disapears when ran with the iPad and an apple TV, it seems there might a bug in the simulator. In future i shall always run my code on real ios devices.

How to present a (no nib) ViewController

I've created a ViewController (without nib files), so how do I load this viewController in the app delegtate? my current code is:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
viewController = [[MyCustomViewController alloc] init...]; // I use a custom init method
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
And how can I use the presentModalViewController method to show new view controllers of the same "CustomViewController" class?
THANKS for the help!
NOTE: By the way, I do see that this code does call my initialization method, and my ViewDidLoad method in my customViewController is being called however the screen is still black....
It looks like your properties are not set up correctly.
Check this line:
viewController = [[MyCustomViewController alloc] init...]; // I use a custom init method
self.window.rootViewController = self.viewController;
check that self.viewController is okay, and there's nothing stopping you from just doing:
self.window.rootViewController = viewController;
Whoops, I was just missing this code in my viewDidLoad Method:
self.view.frame = CGRectMake(0, 0, 320, 480);
self.view.backgroundColor = [UIColor whiteColor];
So everything was working, but the screen by default is black and without a frame.
I had to do just that in one of the apps I'm working on. Try typecasting your view controller
CDViewController *viewController = (CDViewController*)self.window.rootViewController;
viewController.managedObjectContext = self.managedObjectContext;
viewController.managedObjectModel = self.managedObjectModel;
// Override point for customization after application launch.
return YES;

App crash with "Unable to restore previously selected frame" message

I can't figure out why that code leads to app crash.
AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.rootViewController = [[[RootViewController alloc]init]autorelease];
[self.window setRootViewController:self.rootViewController];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Here is RootViewController.m code
-(void)loadView
{
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 10, 10)];
[view setBackgroundColor:[UIColor lightGrayColor]];
[self.view addSubview:view];
[view release];
}
I get that message in the debugger
Unable to restore previously selected frame.
loadView is supposed to set the view. It is called when self.view is nil. Now you're calling [self.view addSubview:view]; UIKit calls loadView, and that creates an infinite recursion. You're supposed to do self.view = view; here.
loadView is responsible to set the view first. you missed to do that. Instead you added a view to self.view.
Change the code by below line:
self.view = view;
instead of [self.view addSubview:view];
Also it is advisable to call [super loadView] before returning from the function.