ViewController is leaving 20px white from lower part of screen when pushed - iphone

I am using multiple controller during launch of an application in app delegate. One controller is for registration and the second controller is tabbar. tabbar was loading fine but when I pushed registration controller on window, contents went up by 20 units and I have good white blank screen at bottom. Therefore I recreated frame of my registration view controller in its viewdidload method and slided it 20 units down. The code is
self.view.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height);
and code in my app delegate for launch application was
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (![self accountExists]) {
//code if account does not exists on iphone app database
self.registerAccount = [[registerViewController alloc] initWithNibName:#"registerViewController" bundle:nil];
[window addSubview:registerAccount.view];
}
else if([self autoLoginForAnyAccount]){
//code for autologin to app
}
else {
self.tabBarController.selectedIndex = 1;
self.tabBarController.delegate = self;
[window addSubview:tabBarController.view];
}
[window makeKeyAndVisible];
return YES;
}
if anyone knows why there is a white space at bottom when registration controller is pushed then please share it with me.

Recently, I have passed through with the same problem. After referring so many blogs & Q&A forums, I found the white space problem is due to improper frame settings.
Below is the solution, that works very fine on my side...
[self.view setFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height)];
Hope, this will help you out.
Regards,
iApple.

I figure out the issue but not the reason. Issue was size of the window i.e. In my code i was creating instance of registerViewController therefore its size was size of the window minus size of the status bar(since it is a view controller which must be displayed below status bar). When i pushed registerViewController onto window then because of some reason (i dont know why) view controller failed to recognize status bar in the header and 20px of registerViewController was displaying behind status bar. then I tried code registerAccount.view.frame = window.frame; which sets the frame of my registration controller equals to window controller. This removed blank white screen at the bottom and view now taking whole of the window size but still 20px was behind status bar since my view controller was blind to see existance of status bar. I tried to remove status bar using code which showed my whole controller on the screen but I wanted status bar at the top too.
I figure out my way by adding UIViewcontroller object in my mainWindow.xib file(just like my tab bar controller) and I pointed its class to be registerViewController and loaded nib of registerViewController. i also removed line self.registerAccount = [[registerViewController alloc] initWithNibName:#"registerViewController" bundle:nil];
and replaced in my delegate .h file registerViewController *registerAccount; with UIViewController *registerAccount; and in mainWindow.xib file I pointed my newly added view controller to this controller. Now everthing is working fine but I still dont know why viewcontroller failed to see status bar when I pushed instance of registerViewController.
if anyone knows the reason then please share here with me.

Related

iOS State Restoration with custom container view controller (MMDrawerController)

Setup
I have a sliding menu custom container view controller (MMDrawerController) controlling a center view controller and a slide out left menu/drawer. Just like the Facebook app and hundreds of others.
Opening the drawer on the left and tapping a menu item replaces the center view controller.
What's Working
If I open the app, press a button on the first center view controller (which changes the background color), I can kill the app and successfully restore the background color. Perfect.
What's Not Working
If I choose another center vc to load (by opening up the menu/drawer and selecting a menu option) and then kill the app, the app won't restore to that view controller.
What I'm Doing
In my parent view controller I'm encoding the left and center view controllers so I can recreate them on restore.
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.centerViewController forKey:#"centerVC"];
[coder encodeObject:self.leftDrawerViewController forKey:#"leftDrawerVC"];
[super encodeRestorableStateWithCoder:coder];
}
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
// if I don't change the center view controller, these values
// get logged out as expected
NSLog(#"leftDrawer: %#", [coder decodeObjectForKey:#"leftDrawerVC"]);
NSLog(#"center: %#", [coder decodeObjectForKey:#"centerVC"]);
[super decodeRestorableStateWithCoder:coder];
}
In the flow where I change the color on the first center view controller, during decoding I can get back the center and left View Controllers successfully. However in the flow where I select a new center vc to load, during decoding those objects are nil.
How do I set up my custom container view controller to properly encode references to it's children in a way that I'm guaranteed to get them back while decoding?
UPDATE 1
Using the restorationArchiveTool I inspected the archive after running through the scenario that doesn't restore properly, and the archive does in fact contain the hierarchy of encoded objects that I'd expect. I still can't figure out though why those previously encoded view controllers end up being null during decoding.
UPDATE 2
If you look at the comments section of this gist, you can see that all the proper encode/decode calls seem to be happening on saving and restoring. I'm wondering if in my app delegate, when i initially set up my root view controller (the instance of mmdrawercontroller) if I'm somehow clobbering the state restoration? Here's what I'm doing:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavController *centerNav = [[UINavController alloc] initWithRootViewController:[FeaturedViewController new]];
centerNav.restorationIdentifier = #"centerNav";
UINavigationController *leftDrawerNavController = [[UINavigationController alloc] initWithRootViewController:[LeftDrawerViewController new]];
leftDrawerNavController.restorationIdentifier = #"leftDrawerNav";
MMDrawerController *drawerViewController = [[MMDrawerController alloc] initWithCenterViewController:centerNav leftDrawerViewController:leftDrawerNavController];
// no restoration class, since this will always be created before state restoration resumes, and therefore will be found implicitly
[drawerViewController setRestorationIdentifier:#"mmDrawer"];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = drawerViewController;
self.window.restorationIdentifier = NSStringFromClass([UIWindow class]);
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return true;
}
I have done similar with MMDrawerController and believe the problem is that you are not providing UIKit with a way to create all of the possible center view controllers when it is restoring state. Note that when you encode a controller, all that gets saved is the restoration ID for that controller. To be restored when you next start the app UIKit needs to be able to obtain an instance of the controller -- it won't create one itself. It will try various methods to obtain said instance, as listed here:
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/StatePreservation/StatePreservation.html#//apple_ref/doc/uid/TP40007072-CH11-SW10
Your app may create the default center controller every time (either via a storyboard or manually) so that one works. For others you probably need to either implement a restoration class or implement application:viewControllerWithRestorationIdentifierPath:coder: in your delegate and have it return a new instance of the right type.

InterfaceOrientation issues when popping a ViewController off the stack

I have the beginnings of my app working pretty well but I have one small issue that I can't figure out how to fix.
It's a view based app and I have a NavigationController in my appDelegate file which is pushing various ViewControllers as required. Going in the "forwards direction" everything works well, seems perfect actually, but the problem I have is when VC's are popped off the stack. This is the code I'm using to show the VC and then just using the back button to go back.
UINavigationController *iaxNC = [[UINavigationController alloc] init];
LogInViewController *logInVC = [[LogInViewController alloc] init];
[iaxNC pushViewController:logInVC animated:NO];
[logInVC release];
[_window addSubview:iaxNC.view];
[_window makeKeyAndVisible];
That loads my login view and then the code checks to see if there are any users before it loads the SetUp screen (if there are none) as follows:
setUpVC = [[SetUpViewController alloc] init];
setUpVC.firstUse = self.firstUse;
[self.navigationController pushViewController:setUpVC animated:YES];
[setUpVC release];
The problem happens when I hit the back button from the SetUp view to go back to the LogIn view.
I have a portrait and a landscape view for most of the VC's and these VC's are subclasses of Michael Tyson's TPMultiLayoutViewController. The portrait view is hooked up as *portraitView and also as *view, the landscape view is hooked up as *landscapeView.
The problem is this:
If I push a VC into view and change the orientation of the device before I hit the back button then when I do hit "Back" the previous VC is displayed in its original format (i.e. NOT rotated to the current orientation) it also appears that the lower left corner of the view is in the lower left of the screen. It then "sticks" like that until I rotate the device again and then all is good and functions as expected.
So the thing is I'm working through the contents of the TPMultiView subclass but I don't pretend to understand all of it yet (and therein probably lies my REAL problem) but as a stopgap solution is there a way to force the view of the "pusher" VC to appear in it's previous orientation (albeit briefly - and THEN allow it to rotate once it has been displayed) when the "pushee's" VC is popped?
Does that make sense?
SOLVED IT! The problem was I had included my own viewWillAppear method in LogInVC but I hadn't called [super viewWillAppear] so the effect of the superclass was never really going to work, was it! Thanks for the input. I can recommend the TPMultiView drop in subclass BTW works very nicely.
You should first verify your implementation of shouldAutoRotateToInterfaceOrientation: is correct for all your view controllers.
Then make sure the views of your view controller's have an appropriate autoresizingMask set. If you have created the view controllers and their views in Interface Builder you should set the resizing mask there.
Otherwise in your -loadView or -viewDidLoad methods you should have this line:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;

Difficulty displaying Tab Views in iOS iPhone

I'm new to iOS dev and I have a program that begins by presenting the user a view. This view has two buttons, and depending on which the user clicks, a different tab view will be displayed. The tab view is displayed like this:
betaAppDelegate* delegate = (betaAppDelegate*)[[UIApplication sharedApplication]delegate];
acquireData *ac_view = (acquireData*)[[acquireData alloc] init];
[delegate.window addSubview:ac_view.view];
[self.view removeFromSuperview];
[self dealloc];
The tab view is ac_view.view. When I run the application in the simulator, instead of displaying my tab view with three tabs, it displays a white screen with a thin black bar (empty tab dock) on the bottom. It's encouraging to at least see something be displayed! But I've been trying without success for a while to get it to display my tabs. The .xib file looks correct. It has the three tabs at the bottom, and each of the three tabs say in the interface builder that they're loaded from xxxxxxx, so the linking appears correct...
Thank you!
I'm going to presume you're using the UITabBarController.
You can either set one up by adding the tabs in interface builder and then setting which xibs the individual tabs load up. It sounds like you have done this. After that there is no code you need to write to get the tab bar working to switch between your three view controllers.
You can also set up the TabBarController programatically.
This would be the programmatic way and would go into you application delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UITabBarController * aTabBarController = [[UITabBarController alloc] init];
NSArray * array = [[NSArray alloc] initWithObjects:controller1, controller2, controller3, nil];
[aTabBarController setViewControllers:array animated:NO];
[array release];
self.window.rootViewController = aTabBarController;
[self.window makeKeyAndVisible];
[aTabBarController release];
return YES;
}
You would then see a tab bar with three tabs that correspond to controller1, 2 and 3 (your custom view controllers)
To set the icon and text and things its as easy as reading the documentation and seeing
Tab bar items are configured through
their corresponding view controller.
To associate a tab bar item with a
view controller, create a new instance
of the UITabBarItem class, configure
it appropriately for the view
controller, and assign it to the view
controller’s tabBarItem property.
Just a final word of warning in Objective C you should never call dealloc yourself. Dealloc is called by the system when an objects retain count reaches 0. Read into how to retain and release objects to get the hang of how this all works.
Good luck

Modal View appearing half offscreen

When I try to present a modal view controller, it functions as its supposed to, but it appears with the wrong orientation and only goes half way along the screen (only the top half of it is showing). The code seems simple enough -
-(void)showAboutView {
AboutViewController *aboutViewController = [[AboutViewController alloc] init];
if (aboutViewController != NULL) {
[self presentModalViewController:aboutViewController animated:YES];
}
}
All the shouldAutorotateToInterfaceOrientation are set to "landscapeRight"
I realise I'm probably doing something really stupid, but I can't figure out what it is... any help gratefully received!
If it's showing up in the wrong orientation, I'd say that you've got an issue in your XIB file for AboutViewController.
Did you create that XIB in a different orientation than your app is currently in? Look at the third tab on the property inspector -- is the autoresizing set up properly?

presentModalViewController problem

I have a problem, using presentModalViewController to display a UIView. Within the Application I have a NavigationController with a list of Items. Touching a Cell calls the first ViewController, responsible for only showing a background picture. Within the viewDidLoad method I create another ViewController which has a UiScrollView, displaying some information about the item.
So far so good.
Now, an item can consist of subitems, so if I click on a subitem, I use presentModalViewController to create a new instance of the first ViewController. My problem is, that this newly displayed controller is show around 180px(a guess) lower than it should be. I thought, this was due to relative coordinates I set wrong, but if I click on a subitem with the new (lower) controller, I would expect it to be displayed lower again (say 360px) - relative to the topleft corner of the Iphone.
Anyway, this doesnt happen. My question is why is the new controller displayed lower than it should be/I expect it to be. Spent a few hours on this, so any ideas are appreciated!
Edit: Some Code - this is the part, where i present the controller:
ItemDetailsViewController *itemScrl= [[ItemDetailsViewController alloc] initWithNibName:#"ItemDetailsViewController" bundle:nil];
itemScrl.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:itemScrl animated:YES];
This is the part, where I create the scrollable View:
- (void)viewDidLoad {
[super viewDidLoad];
ItemScrollController *itemScrl = [[ItemScrollController alloc] initWithNibName:#"ItemScrollController" bundle:nil];
itemScrl.title = self.title;
itemScrl.view.frame = CGRectMake(20 , 0, 280, 400);
[self.view addSubview:itemScrl.view];
}
I think my problem was, not having added a Navigationbar in the parentviewController and not telling the subview, that there actually was one. There are various ways to do this, I suppose, anyways, in IB you can checkmark the Navigationbar box for the actual view and thus it shouldnt be resizing anything.