Weird UI problem when modal view is dismissed - iphone

As shown in the screenshot below, i have a UITableView with some info and upon selecting a row an ABUnknownPersonViewController is invoked. In order to be able to able to dismiss that and go back to the UITableView I have this code:
ABUnknownPersonViewController *unknownPersonView = [[[ABUnknownPersonViewController alloc] init] autorelease];
[unknownPersonView setUnknownPersonViewDelegate:self];
[unknownPersonView setDisplayedPerson:personRecord];
[unknownPersonView setAllowsAddingToAddressBook:YES];
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Επιστροφή" style:UIBarButtonItemStylePlain
target:self action:#selector(goBackToView)];
unknownPersonView.navigationItem.title = #"Προσθήκη στις επαφές";
unknownPersonView.navigationItem.leftBarButtonItem = anotherButton;
navigationController = [[[UINavigationController alloc] initWithRootViewController:unknownPersonView] autorelease];
//navigationController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease];
//self.navigationItem.rightBarButtonItem = anotherButton;
[self presentModalViewController:navigationController animated:YES];
} // didSelectRowAtIndexPath ends here
- (IBAction)goBackToView {
[self dismissModalViewControllerAnimated:YES];
}
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person {
// CallerIDAppDelegate *delegate = (CallerIDAppDelegate *)[[UIApplication sharedApplication] delegate];
[navigationController dismissModalViewControllerAnimated:YES];
}
The problem (as you can see) is that when the ABUnknownPersonViewController is dismissed by the "Επιστροφή" button, which is "Back" actually, the view holding the tableView and the blue UIButton is moved a couple of pixels to the bottom!
Any help on what could be causing this?
Screenshot http://dl.getdropbox.com/u/1237004/problem.jpg

Debug this by checking your view's frame in -viewWillAppear, -viewDidAppear, -viewWillDisappear, and -viewDidDisappear.
Also check the view's autoresizingMask, and the parent view's autoresizesSubviews property.

I'm not sure I see the value of setting up a navigation controller here. You could just present the ABUnknownPersonViewController with [self presentModalViewController: unknownPersonView];. If you're doing it for the sake of picking up the visual navigation bar with the back button, then just add a nav bar and button to the unknown person view.
It seems like a mixed metaphor to be creating a UINavigationController but then not using its usual navigation methods (e.g., pushViewController:animated: and popViewControllerAnimated:) and instead using the modal methods inherited from UIViewController.

It seems that adding this line:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
in my viewWillAppear: made the view not to move when the modal view controller is dismissed. However now the initial position was already slightly dislocated to the bottom but fixed it by moving all the outles in IB to the top so it looks ok.

Related

How to load a UICollectionViewController on clicking a button in the navigation bar?

I have a class, DisplayOptViewController, which is a subclass of UICollectionViewController.
I want to display this CollectionViewController when the user clicks a button in the Navigation Bar on my current page. I am able to load the CollectionView on button Click but the Navigation Bar is not coming. I want the user to be able to see a back button in the navigation Bar and clicking the button should take him back to the current page.
I tried to do this via storyboard as well as programmatically. When I try this via the Storyboard, the ViewController itself is not displayed and when I create the view controller object programmatically, I am not getting the Navigation Bar. Any idea how to to this?
I tried to add this code to my viewDidLoad method in DisplayOptViewController:
UINavigationBar *navBar=[[UINavigationBar alloc] init];
[[self navigationController] setNavigationBarHidden:NO animated:YES];
[self.navigationController.navigationBar addSubview:navBar];
But the Navigation Bar still didn't come. Kindly help.
update
I am loading the UICollectionView here
UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setItemSize:CGSizeMake(140, 50)];
[aFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
DisplayOptViewController *vc=[[DisplayOptViewController alloc] initWithCollectionViewLayout:aFlowLayout];
[self presentViewController:vc animated:YES completion:nil];
You have a few things that i question,
[self.navigationController.navigationBar addSubview:navBar];
you are adding a navigation bar to a navigation bar.... do this instead
[self.navigationController setNavigationBar:navBar];
second
[self presentViewController:vc animated:YES completion:nil];
you are presenting the controller.... not pushing/poping it....
[self.navigationController pushViewController:vc animated:YES];
try that in when you do it programmatically
as for the storyboard maybe you don't have the segues set up correctly, or properties not set right or something... but i can't debug it like this
If you have a navigation based project, then you have to initialize the navigation controller in the app delegate itself. Try the code below to make the navigation bar visible,
In application didFinishLaunchingWithOptions method,
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[self viewController]];
[[self window] setRootViewController:navigationController];
[self.window makeKeyAndVisible];
return YES;
Now your navigation bar will appear.

How to keep UINavigationController's UINavigationBar transparent when modally presenting a controller?

I've got a fullscreen view inside of a UINavigationController. When I attempt to present a modal view on top of it, the UINavigationBar changes to opaque, pushing down the content, before the modal view animates. How do I keep this from happening?
ContextMenuViewController *cmvc =
[[ContextMenuViewController alloc] initWithNibName:nil bundle:nil];
[cmvc setDelegate:self];
UINavigationController *navControl =
[[UINavigationController alloc] initWithRootViewController:cmvc];
[cmvc release];
[navControl.navigationBar setBarStyle:UIBarStyleBlackTranslucent];
[self.navigationController presentModalViewController:navControl animated:YES];
[navControl release];
[[UIApplication sharedApplication]
setStatusBarStyle:UIStatusBarStyleBlackTranslucent
animated:NO];
The UINavigationController's root view does not have any transparency (status bar nor UINavigationBar), only the pushed controllers have the transparency.
I created a video of the issue: http://www.youtube.com/watch?v=KSFvzTR5Ejk
Example source at: http://cl.ly/7lu2
I tried your code in a very small test project and didn't see the issue you describe. I suggest you do the same thing. Start with the Navigation-based Application template. In the main nib, check the navigation controller's Wants Full Screen and Resize View From Nib, and make its nav bar transparent. In the root view controller's nib, put a button that you can respond to, set up the action, and paste in your code. Create the ContextMenuViewController class; there is no need to give it a nib.
Run the app and press the button. The modal view slides into place, with a transparent nav bar, without affecting the transparency of the nav bar that already exists and without moving the existing content.
So now, once you've proved to yourself that it works in this simple project, it's just a question of locating what you're doing different from that in the real project.
Try setting the bar styles during viewDidLoad for the root View Controller.
HERE YOU GO )
OptionsViewController *detailViewController = [[OptionsViewController
alloc] initWithNibName:#"OptionsViewController" bundle:nil];
UINavigationController *optionsController = [[UINavigationController
alloc] initWithRootViewController:detailViewController];
[detailViewController release];
optionsController.navigationBar.translucent = YES;
optionsController.navigationBar.opaque = YES;
optionsController.navigationBar.tintColor = [UIColor clearColor];
optionsController.navigationBar.backgroundColor = [UIColor
clearColor];
optionsController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:optionsController animated:YES];
[optionsController release];

Three20 TTLauncher Issues

So, I'm having some issues with my implementation of the Three20 TTLauncherView. I am using their code, not a fork (although I have heard of rodmaz's version), and I can't get it to work properly. This is what my app looks like.
alt text http://img709.imageshack.us/img709/8792/screenshot20100715at409.png
I removed the icon image, that's not the issue. The issue is, at the top there is no Navigation bar at all, and I believe also causes the white strip at the bottom, which appears to have the same dimensions as a Nav Bar. I've spent quite a while looking through their code and can't figure this out at all. It looks like their Navigation bar (as seen in their Catalog example app) stems from the TTTableViewController, or something further up. However, my app starts like the Facebook app does, not into a table, but into the TTLauncherView. So... how do I get the Navigation bar into my TTLauncher view, if it goes "App Delegate -> TTLauncherView Subclass"
Thanks for your help!
Edit:
Added the code I used. I put this in my app delegate, wrapping my first view with the UINavigation Controller, and it worked just as I wanted!
MainViewController *aController = [[MainViewController alloc] initWithNibName:nil bundle:nil]; //my Main view
self.mainViewController = aController;
[aController release]; //release for Memory Management
self.mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;
UINavigationController *navigationController = [[UINavigationController alloc] init];
[navigationController pushViewController:self.mainViewController animated:NO]; //Gets the main view on the screen
[window addSubview:navigationController.view];
You simply wrap the view with a navigation bar before you push the new view. As an example, here is a snippet of my code where I present a modal view controller with a navigation bar.
- (IBAction) showNewNavView: (id) sender
{
// Present it as a modal view and wrap the controller in a navigation controller to provide a navigation bar for the Edit and Save buttons
ModalViewController *addController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
addController.delegate = self;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addController];
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[addController release];
}
If you want to add any buttons or set the title of it, you need to do that in the viewDidLoad method of the view that you are pushing (i.e. your TTLauncher view)

toolbarItems not being pushed with view

I have a NavigationController based iPhone app that has a navigationBar and a toolbar. Here is basically how it works:
The applicationDelegate pushes a "SplashScreen" onto the RootViewController as a modal view. While the splash screen is up, the application does some work and based on the user's location will either just dismiss the modal view OR will dismiss the modal view and push another view onto the navigation stack.
Both the RootViewController and the child view have toolbars with an Add button. My problem is this: when the 2nd view is pushed automatically, the Add button calls the code for its PARENT controller. If you dismiss this and then press the add button again, it calls the correct code.
Here is some of my code.
in the viewDidLoad of the RootViewController I have:
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addClicked:)];
[self setToolbarItems:[NSArray arrayWithObjects:addButton, nil]];
in the viewDidLoad of the Child Controller (LocationListsController) I have:
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addClicked:)];
[self setToolbarItems:[NSArray arrayWithObjects:addButton, nil]];
(yes the same code, they both have addClicked events)
in the RootViewController, viewWillAppear is where I actually push the child view:
if (((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex != -1)
{
GeoLocation *location = [((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).locations objectAtIndex:((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex];
((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex = -1;
if (lController == nil)
{
LocationListsController *aController = [[LocationListsController alloc] initWithLocation:location];
self.lController = aController;
[aController release];
}
[[self navigationController] pushViewController:lController animated:YES];
}
The pushing of the view works fine. The only problem I have is the addButton on the toolbar. Does anyone have any ideas?
Try pushing the "child" view controller from viewDidAppear instead of viewWillAppear.

Gap on Navigation Controller

I've got a button on a view. When I click on it, it should load another view, one with a novigation controller. So far I've got this, the button calls this method:
-(IBAction)loadOptionsView:(id)sender {
if (self.optionsRootController == nil) {
//optionsRootController is declared as: UINavigationController *optionsRootController;
optionsRootController = [[UINavigationController alloc] init];
//Options is a UIViewController
Options *myOptions = [[Options alloc] initWithNibName:#"OptionsMenu" bundle:nil];
[optionsRootController pushViewController:myOptions animated:NO];
[myOptions release];
}
[self.view addSubview:optionsRootController.view];
}
What happens when I click the button is that it loads the xib file OptionsMenu on top of the current screen, but there's a gap at the top of the size of the status bar, so I can see the view below. Any help? What's the right method to load a new view that contains a navigation controller?
Thank you all!
I solved this issue by placing after:
[optionsRootController pushViewController:myOptions animated:NO];
this line:
[optionsRootController.view setFrame: [self.view bounds]];
Nice and easy!
I think UINavigationController's designated initializer is
- (id) initWithRootController:(UIViewController *)rootController
So your code above would be better expressed as
//optionsRootController is declared as: UINavigationController *optionsRootController;
//Options is a UIViewController
Options *myOptions = [[Options alloc] initWithNibName:#"OptionsMenu" bundle:nil];
optionsRootController = [[UINavigationController alloc] initWithRootController: myOptions];
[myOptions release];
Is the VIew in your nib the right size for the whole screen? Try turning off the simulated status bar in IB.