iOS 7 resizing main view to adjust for status bar - resize

Rather than having to adjust every single XIB in my application, I was hoping to just resize the main view.
I did this in AppDelegate, with partial success:
if (kCFCoreFoundationVersionNumber > kCFCoreFoundationVersionNumber_iOS_6_1) {
NSLog(#"iOs 7 detected");
frame.origin.y += 20.0;
frame.size.height -= 20.0;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
}
self.window = [[[UIWindow alloc] initWithFrame:frame] autorelease];
The whole window moves down, the status bar shows nicely, BUT all my views are now 20 pixels too tall for the screen, as if my -20 for the height did not have any effect.
Does anyone have any idea as to how I can get the main window to be the right height?
Thanks!

A possible solution could be the following: Instead of change the window size you could try to change the root view controller frame size. This solutions works for me . As a reference here is my code. I have added this inside my root view controller and I call it in my custom init method:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
CGRect frame=self.view.frame;
frame.origin.y=20;
frame.size.height-=20;
self.view.frame=frame;
}

I got it to work by overriding the root viewcontroller and attach my "main" viewcontroller to that. Maybe there is a better way to work and do this, this is one way.
In your AppDelegate (applicationDidFinishLaunch method)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Override rootviewcontroller with an empty viewcontroller
window.rootViewController = [[UIViewController alloc] init];
//Setup my custom viewcontroller
MyViewController *vc = [[MyViewController alloc] init];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[window.rootViewController addChildViewController:vc];
[window.rootViewController.view addSubview:vc.view];
// Put in the desired size and position.
vc.view.frame = CGRectMake(10.0, 100.0, 300.0, 100.0);
...
Just for fun. If you are doing your project with StoryBoard, same process but fetching the StoryBoard identifier. Note that in this case you must set the StoryBoard ID in Interface Builder for your main viewcontroller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
// Fetch viewcontroller from the storyboard ID that you have set in Interface Builder
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MyMainViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[window.rootViewController addChildViewController:vc];
[window.rootViewController.view addSubview:vc.view];
// Put in the disired size and position.
vc.view.frame = CGRectMake(10.0, 100.0, 300.0, 100.0);
...

Related

OS X how to designate startup viewcontroller

I am developing a simple browser project on mac, i didn't use the default viewcontroller.
Instead, I write a viewcontroller class BrowserViewController.
and write follow in appdelegate
#interface AppDelegate()
#property (nonatomic, strong) BrowserViewController *browserController;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
self.browserController = [[BrowserViewController alloc] init];
[self.window makeKeyWindow];
[self.window setContentView:self.browserController.view];
}
#end
But when the app start up it lead to the default viewcontroller not the BrowserViewController. I really don't know the reason.
Thanks for the help, i have solve this problem. My solution is like this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
//set the frame of the window fit to the device's frame
//
self.window = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO ];
//
//
self.browserController = [[BrowserViewController alloc] init];
//set contentView
//
self.window.contentViewController = self.browserController;
//this is setting global backgroundColor of the window
//
self.window.backgroundColor = [NSColor whiteColor];
//this means the window is the window that will receive user interaction.
//
[self.window makeKeyAndOrderFront:self];
//[self.window makeKeyWindow];//NOTE: This is not working.
}
You can select Is Initial Controller in the storyboard.
Sounds like you're looking for (inside your didFinishLaunchingWithOptions method):
self.browserController = [[BrowserViewController alloc] init];
[self.window setRootViewController: self.browserController];
[self.window makeKeyAndVisible];
If you want it programmatically:
Note
This is for iOS, but the logic are identical. Hope this will be useful for some reason.. :)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//set the frame of the window fit to the device's frame
//
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//what you have above is correct
//
self.browserController = [[BrowserViewController alloc] init];
//you can also directly set it like
//
BrowserViewController *mainView = [[BrowserViewController alloc] init];
//this is the most important, you need to set the window's rootViewController
//
self.window.rootViewController = mainView;
//this is setting global backgroundColor of the window
//
self.window.backgroundColor = [UIColor whiteColor];
//this means the window is the window that will receive user interaction.
//
[self.window makeKeyAndVisible];
return YES;
}
Hope this is helpful and informative.. Cheers! :)

UINavigationBar is not rotating

I am experiencing a little problem. I'm trying to develop an app with UINavigationController bar but it is not rotating although my tableView is.
Just a little introduction so you know what my application is right now : I have a UITableView which is created in IB and linked in my class ViewController.h and a UINavigationController created in the appDelegate.h. All the items in the tableView can be clicked and it will slide to another viewController but this part is not important for now. I'm just trying to support rotation in the main view for now.
I create the UINavigationController in my AppDelegate.h like this:
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UINavigationController *navigation;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UIViewController *viewController;
And then in AppDelegate.m I do this :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
ViewController *viewController = [[ViewController alloc] init];
viewController.title = #"Agrinuvo";
[navigation pushViewController:viewController animated:NO];
navigation = [[UINavigationController alloc] initWithRootViewController:viewController];
navigation.navigationBar.tintColor = [UIColor darkGrayColor];
[[UIBarButtonItem appearance] setTintColor:[UIColor orangeColor]];
[_window addSubview:navigation.view];
}
I have tried in my ViewController.m viewDidLoad method these :
self.navigationController.navigationBar.autoresizesSubviews = YES;
self.navigationController.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
I am able to resize the UINavigationBar but I cannot rotate it for the life of me (still in ViewController.m) :
-(void) orientationChanged
{
CGRect frame = self.navigationController.navigationBar.frame;
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait)
{
self.view.transform = CGAffineTransformMakeRotation(0);
frame.size.height = 44;
frame.origin.y = 15;
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
self.view.transform = CGAffineTransformMakeRotation(M_PI * 1);
frame.size.height = 44;
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
self.view.transform = CGAffineTransformMakeRotation(M_PI * -0.5);
frame.size.height = 32;
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft)
{
self.view.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
frame.size.height = 32;
}
self.navigationController.navigationBar.frame = frame;
}
Ah yes, I also tried this method in all of my controllers and it is returning YES in all of them but the NavigationBar still does not rotate.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
So I'm wondering if it is actually possible to rotate a NavigationBar. Also do I create it like it should be created?
Should I be initiating my UINavigationController this way or should I be creating it in IB and link it to a .h class?
Sorry for the long read and thank you for any help you can provide
You should make your navigation controller the root view controller of the window. Also, in your applicationDidBecomeActive:method, you have this line: [navigation pushViewController:viewController animated:NO]; which you use before you've instantiated navigation, so that line isn't doing anything.

NavigationBar not displaying properling when pushViewController

The problem is pretty simple to understand with pictures.
I have a UINavigationController that allow the user to switch between to views.
The first view contains a search bar and a table view like so :
The second is a basic view where information about the cell are display
When I click on the search bar, the navigation controller gets hidden and the search bar is now at the top.
Now, if I click on a cell, it goes to the second views, but the navigation bar is first hidden like below :
And then, it automatically appears like that :
I have tried a couple of things like show the navigation bar before pushing the next view controller but it is quite ugly..
Does anyone know how to have the show the navigation bar directly on the second view (like in the contact application)?
[UPDATE] : Code
AppDelegate.m (I'm talking about navigationcontroller2)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController1.managedObjectContext = [self managedObjectContext];
viewController2.managedObjectContext = [self managedObjectContext];
viewController1.viewController2 = viewController2;
UINavigationController *navigationcontroller1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[navigationcontroller1.navigationBar setTintColor:[UIColor lightGrayColor]];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[navigationcontroller2.navigationBar setTintColor:[UIColor lightGrayColor]];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller1, navigationcontroller2, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
FirstView.m
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!noResultsToDisplay) {
PinDetailsViewController *pinDetailsViewController = [[PinDetailsViewController alloc] initWithNibName:#"PinDetailsViewController" bundle:nil];
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
Pin *pin = (Pin *) managedObject;
[self.navigationItem setTitle:#"Pins"];
[self.navigationController pushViewController:pinDetailsViewController animated:YES];
[pinDetailsViewController updateWithPin:pin];
}
}
If you need anything else, just ask but I think it's all there.
Try to use this code in each viewcontroller.
- (void) viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
Before you push the new view controller, you should unhide the navigation bar:
[self.navigationController setNavigationBarHidden:NO animated:YES];
I had a similar problem with the position of my navbar. Mine was moving up behind the status bar, and I fixed the issue by manually setting the navbar frame:
-(void)adjustNavBarOrigin
{
CGRect r = self.navigationController.navigationBar.frame;
r.origin = CGPointMake(0, 20); // 20 is the height of the status bar
self.navigationController.navigationBar.frame = r;
}
I had to call this method in a number of places, including viewWillAppear: and didRotateFromInterfaceOrientation:, but it worked a treat :)
Hiding the UINavigationBar can disturb the properties sometimes. Try using the property alpha instead of hidden.

UITabBarController with a UIPopOverController with Multiple Views

I am working on a small app, according to the requirement the app should have a tabBarItem with 3 items. For this I have programmatically created the tabBarController in the AppDelegate.m file and added the 3 different viewControllers, instantiated them and everything is working good. I see the tabBarItems and all views are working. In one of the views lets say in SecondViewController I show a popOverController where I used a UITableView and populate it with items. When I click one of the items it should show another view lets say sendFeedback. Until there everything is working fine, but as soon as this sendFeedback is presented as the modal view, it occupies the whole app i.e it hides the tabBarItem.
I present the important pieces of code here for review:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
viewController1.title = #"First";
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController2.title = #"Second";
UITableViewController *tableView3 = [[tableViewController alloc]initWithNibName:#"tableViewController" bundle:nil];
tableView3.title = #"Third";
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, tableView3 ,nil];
self.tabBarController.delegate = self;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[viewController1 release];
[viewController2 release];
[tableView3 release];
return YES;
}
In my popOverViewController.m file I am checking which row is selected in the table according to that I present the view
#pragma mark - TableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sendFeedback *sendEmailViewController = [[sendFeedback alloc]initWithNibName:#"sendFeedback" bundle:nil];
downLoad *downloadFilelViewController = [[downLoad alloc]initWithNibName:#"downLoad" bundle:nil];
if (indexPath.row == 0)
[self presentModalViewController:sendEmailViewController animated:YES];
else
[self presentModalViewController:downloadFilelViewController animated:YES];
}
Can anyone guide me how to overcome this with the multiple views. In case if anyone requires more information from my side I would be glad to provide.
NOTE: It is the same with the other view (downLoad) as well
EDIT: Here is how I am initializing my PopOverController in the AppDelegate.m file
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if([viewController isKindOfClass:[SecondViewController class]]){
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 85);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Thanks
Modal view controllers are used to "block" your application and fulfill a task before you can proceed. So modal view controllers are not what you want to use.
Instead wrap your controllers which have to be shown in the popover in a navigation controller. In the tableView:didSelectRowAtIndexPath: method you can push the corresponding view controller to the navigation stack.
To slove your problem:
At the place where you create the popovercontroller initialize it with a new UINavigationController. And the navigation controller you have to initialize with a rootviewcontroller namely PopOverViewController.m.
PopOverController *popoverContentController = [[PopOverController alloc] init];
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:popoverContentController];
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContentController];
And in PopOverController.m
if (indexPath.row == 0)
[self.navigationController pushViewController:sendEmailViewController animated:YES];
else
[self.navigationController pushViewController:downloadFilelViewController animated:YES];

How to trigger navigationController:willShowViewController delegate method in AppDelegate

How can I trigger the navigationController:willShowViewController delegate method for my implementation below so that all the view controllers in the navigation controller will conform to the colorWithHexString #faf6f5?
Currently, my FirstViewController will be displayed but it doesn't seem to call the delegate method to change the color of it's navigation bar (as well as for all other view controllers that are stacked onto the navigation controller subsequently). Note that I have already added the "UINavigationControllerDelegate" to my app delegate header file.
//In App Delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Set First View
FirstViewController *firstView = [[FirstViewController alloc]init];
// pushes a nav con
UINavigationController *tempNavcon = [[UINavigationController alloc]initWithRootViewController:firstView];
self.navcon = tempNavcon;
[self.window addSubview:navcon.view];
}
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
navigationController.navigationBar.tintColor = [UIColor colorWithHexString:#"#faf6f5"];
}
is there a reason why you are trying to change the tintColor in an event method rather than when the UINavigationBar instance is created?
Here's how you do it. (Note that UIColor doesn't accept hex values; you should use an RGB value, or check this page.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Initialize your view controller.
FirstViewController * firstView = [[FirstViewController alloc] init];
// Create an instance of a UINavigationController. Its stack contains only firstView.
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:firstView];
//Here is where you set the color of the navigationBar. See my note above for using RGB.
navController.navigationBar.tintColor = [UIColor greenColor];
// You can now release the firstView here, navController will retain it
[firstView release];
// Place navigation controller's view in the window hierarchy
[[self window] setRootViewController:navController];
[navController release];
[self.window makeKeyAndVisible];
return YES;
}