How to display NavigationController-background within a UIPopoverController on iPhone - iphone

How can i display the background of the NavigationController (including title/buttons) in my UIPopovercontroller on the iPhone?
At the moment it looks like that:
In my PopoverView-ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.hidden = NO;
self.navigationController.navigationBarHidden = NO;
self.navigationItem.title = #"self.navigationItem.title";
}
When calling Popover:
InfoView *iv = [[InfoView alloc] initWithNibName:#"InfoView" bundle:nil];
UINavigationController *uc = [[UINavigationController alloc] initWithRootViewController:iv];
self.pop = [[UIPopoverController alloc] initWithContentViewController:uc];
[self.pop setDelegate:self];
[self.pop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:true];
It should look like this:

At first UINavigationController doesn't have own background, it shows background of content view controller. If you can show popover with navigation controller successfully, then check your InfoView. Does it's view has some background?
Second, I tried to execute your code multiple times in different configurations on iPhone, but always have received error
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UIPopoverController
initWithContentViewController:] called when not running under
UIUserInterfaceIdiomPad.
And that was not surprise for me. Even if you could make it work, then Apple may reject your application.
2.1 Apps that crash will be rejected - Just test your code on several devices and see result.

your code
InfoView *iv = [[InfoView alloc] initWithNibName:#"InfoView" bundle:nil];
UINavigationController *uc = [[UINavigationController alloc] initWithRootViewController:iv];
self.pop = [[UIPopoverController alloc] initWithContentViewController:uc];
[self.pop setDelegate:self];
[self.pop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:true];
is perfect just hide the default navigation controller and add a navigationBar in the XIB of InfoView.xib and write the cancelButtonAction there to perform the dismissal of the view or the detail of the tableview selection. It Works fine, Please check the image i have done the same way, and believe me it works fine.

Add this to your code before the line [self.pop presentPopoverFromBarButtonItem:se..:
uc.modalPresentationStyle = UIModalPresentationCurrentContext;
See the documentation for the modalPresentationStyle property.

I think you'll need to paste in more of the code for your InfoView controller, as I suspect that's where the problem is.

Have you tried setting up your background view as a class?
[pop setPopoverBackgroundViewClass:bgView];

Related

“Application tried to present modally an active controller” Error in iOS5

I have an error which is causing my app to crash under iOS5 only on the iPad.
The below code is called when the user taps on an item in a uibarbutton item :
- (void)optionSelected:(NSString *)option {
[self.optionPickerPopover dismissPopoverAnimated:YES];
if ([option compare:#"Map View"] == NSOrderedSame) {
NSLog(#"Map View");
MapView * map = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:map];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self action:#selector(removeCurrent)];
map.navigationItem.rightBarButtonItem = rightButton;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[map release];
[rightButton release];
[split presentModalViewController:map animated:YES];
}
Can anyone suggest why this occurring in iOS5 ?
You are getting this error because you are attempting to display the 'map' view controller twice. The first time is as the root view controller of 'navigationController' and the second time is via [split presentModalViewController:map animated:YES].
iOS 5 is being a bit more picky than iOS 4 when you try to do strange things with view controllers. Trying to show the same controller twice is a design problem - you need to work out what you are really trying to do and fix it.
(Also, calling a map view controller 'MapView' rather than 'MapViewController' is really confusing)
This error will also occur if you don't follow these guidelines: Creating Custom Content View Controllers
Basically, you need to call:
[yourVC removeFromParentViewController];
if you've
[parentVC addChildViewController:yourVC];
This error may often be paired with something about "UIViewControllerHierarchyInconsistency"

view controller does not load with content

I have a button that when clicked shows a view controller. The code for that event is:
and my view controller looks like this:
note the segmented control and background image.
Here is my h and m files of my view controller in case you need them:
when I run my app here is how that view control looks on my iPad:
why do the background image and segmented control do not appear? why are contents not being loaded? It looks like another view controller is being loaded but I have already make sure that I am placing the correct name in the string for the view controller.
- (IBAction) vaClick
{
imgVa.image = [UIImage imageNamed:#"bt-valores.png"];
UIViewController *control = [[NuestrosValoresViewController alloc] initWithNibName:#"NuestrosValoresViewController"
bundle:nil];
UINavigationController *navControl = [[UINavigationController alloc]
initWithRootViewController:control];
[self presentModalViewController:navControl animated:NO];
[navControl setNavigationBarHidden:YES];
[control release];
[navControl release];
//UINavigationController *navControl = [[UINavigationController alloc]
//initWithRootViewController:control];
//[self presentModalViewController:navControl animated:NO];
}
should I release it like this? sorry I basically have to translate a power point presentation to an app therefore I know very little about objective-c. thanks for the help and sorry for the dumb question.
You're not setting the root view controller of your UINavigationController.
Use this line instead when initializing the navigation controller:
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController:control];
You'll also want to release navControl after you present it modally. I'll write out the code for you if you post your code instead of using screenshots.

iPhone - Loading a new view and a deallocated object

So I feel like a serious rookie right now, but I have a problem I can't seem to figure out. I have a barebones app, with literally nothing in it except a login screen and a second view containing a tableview. When I add the second view after logging in (I have done this like 4 times before...), the table view goes through its delegates and appears that it's going to load, but something happens. I have enabled my NSZombies, and it appears to be deallocating the new view, right before it appears.
After tracing through it, and building up again piece by piece, it appears to happen after I wire the table to the view as the datasource/delegate in IB. I have set the view as a UITableViewDelegate, and the methods indeed get fired. Does anyone have any idea what might be causing this behavior?
Have you added the 'second'view to an exisitng view using addSubview: or added it to some form of UINavigationController or UITabBarController? When you do this it will automatically increase the retain count and whatever code you have releasing the view won't cause is to be deallocated.
In my AppDelegate application:didFinishLaunchingWithOptions I have something like;
LoginViewController *login = [[LoginViewController alloc] init];
[login setDelegate:self];
loginNavController = [[UINavigationController alloc]
initWithRootViewController:login];
[window addSubview:[loginNavController view]];
And then once login has occured (and succeeded using a protocol/delegate to send the message back to AppDelegate) I call this code;
UIViewController *newView1 = [[UIViewController alloc] init];
UIViewController *newView2 = [[UIViewController alloc] init];
UIViewController *newView3 = [[UIViewController alloc] init];
myTabBarController = [[UITabBarController alloc] init];
myNavController = [[UINavigationController alloc]
initWithRootViewController:newView1];
// nav controller now retaining
[newView1 release];
NSArray *viewControllers = [NSArray arrayWithObjects:myNavController,
newView2,
newView3,
nil];
[myTabBarController setViewControllers:viewControllers animated:YES];
[[myTabBarController view] setFrame:[[UIScreen mainScreen] applicationFrame]];
[window addSubview:[tabBarController view]];
// tab bar controller now retaining
[newView2 release];
[newView3 release];
// remove login from application
[[loginNavController view] removeFromSuperview];
The AppDelegate has the following declared in the header file;
LoginViewController *loginViewController;
UITabBarController *myTabBarController;
UINavigationController *myNavController;
In the dealloc method for the AppDelegate these are released.
This gives me my login page and then when that has processed my views with a top nav all controlled using the bottom tab bar.
Hope this helps in some way.
You have either too many release (or autorelease) calls - or not enough retain calls - in your view loading/transitioning code, but it's impossible to be more specific without seeing that code.
What's probably happening is the autorelease pool is being flushed between your view loading and your view being shown, and that's what's leading the behaviour you describe.

UISplitViewController strange behavior

Hi i have a splitViewController
mapViewController = [[MapViewController alloc] initWithManagedObjectContext:managedObjectContext startingRegion:startingRegion];
distanceViewController = [[DistanceTableViewController alloc] initWithManagedObjectContext:managedObjectContext];
distanceViewController.mapViewController = mapViewController;
setupViewController = [[SetupTableViewController alloc] initWithStyle:UITableViewStyleGrouped map:mapViewController.map];
setupViewController.positionSwitch.on = savePosition;
SearchTableViewController *searchViewController = [[SearchTableViewController alloc] initWithStyle:UITableViewStylePlain managedObjectContext:managedObjectContext];
searchViewController.mapViewController = mapViewController;
tabBarController = [[UITabBarController alloc] init];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UINavigationController *mapNavigationController = [[[UINavigationController alloc] initWithRootViewController:mapViewController] autorelease];
UINavigationController *searchNavigationController = [[[UINavigationController alloc] initWithRootViewController:searchViewController] autorelease];
UINavigationController *distanceNavigationController = [[[UINavigationController alloc] initWithRootViewController:distanceViewController] autorelease];
UINavigationController *setupNavigationController = [[[UINavigationController alloc] initWithRootViewController:setupViewController] autorelease];
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
splitVC.viewControllers = [NSArray arrayWithObjects:searchNavigationController, mapNavigationController, nil];
splitVC.title = #"iMetano";
splitVC.tabBarItem = [[[UITabBarItem alloc] initWithTitle:#"Mappa" image:[UIImage imageNamed:#"mapIcon2.png"] tag:0] autorelease];
NSArray *viewControllersArray = [NSArray arrayWithObjects: splitVC,setupNavigationController,nil];
[splitVC release];
tabBarController.viewControllers = viewControllersArray;
}
When i startup my app in portrait, all works fine.
When i startup my app in landscape this is the result
I see only the view of the first viewController SearchTableViewController with some pixel between the UINavigationController and the status bar
When i rotate in portrait and after i return in landscape i see both viewController's view, but the second have some pixel between the statusBar and the UINavigationControllor
I can't understand why.
apple says not to put a split view controller inside something else, like a tab bar controller
After looking at my code and IB time after time. This is the best that I could come up with. Not sure if is the best one but it works for me. Im loading a default detail view controller. If I load the controller directly in the viewDidLoad then the problem occur. If I load it from the selector the problem goes away. I hope this helps. I have this code in the RootViewController.
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:#selector(loadController) withObject:nil afterDelay:0];
}
-(void)loadController{
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
WebViewController *newDetailViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
[newDetailViewController setTitle:#"Home"];
NewNavController <SubstitutableDetailViewController>*navController = [[NewNavController alloc] initWithRootViewController:newDetailViewController];
detailViewController = navController;
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
}
I had this exact same problem when attempting the combination of tab bar, split view and navigation controllers. I noticed that the alignment gap is only present when the application first fires up and the first tab is auto-selected because it's the first tab in the tab bar controller's array of view controllers. After switching tabs and then coming back to the one with the misaligned nav controller in a split view, there was no alignment problem present. So, to replicate this behavior and get rid of the misalignment when the screen is first rendered I added:
[tabBarController setSelectedViewController:splitVC];
right after setting the view controller array on the tab bar controller. Works like a champ now.
I know this is an old question, but here's the hack I just used to get around this problem for anyone who has a navigation hierarchy like mine:
UITabBarController
Tab0->UINavigationController->MGSplitViewController _or_ UISplitViewController
Tab1->UINavigationController->SomeOtherViewController
Tab2->Etc...
Nothing I tried could get rid of that 20px gap that occurs only once, at bootup, if the device orientation is anything except UIInterfaceOrientationPortrait. The 20px gap is caused by the UINavigationBar for the split view's UINavigationController above having a non-zero origin.y value; most likely, you'll find it to be 20.
Also, I found that this is only a problem if the device is running iOS < 5.0.
I check for this issue in the view controller code of my MGSplitViewController (i.e. self = an MGSplitViewController):
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if(self.doIOS4OneTimeRotationHack == YES)
{
self.doIOS4OneTimeRotationHack = NO;
for(UINavigationController *navController in [self viewControllers])
{
if(navController.navigationBar.frame.origin.y != 0.0f)
{
[UIView animateWithDuration:0.01
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:
^(void)
{
navController.navigationBar.frame = CGRectMake(navController.navigationBar.frame.origin.x,0.0f, navController.navigationBar.frame.size.width,navController.navigationBar.frame.size.height);
}
completion:
^(BOOL finished)
{
//NSLog(#"Shifted navbar 0x%x up!",navController.navigationBar);
}];
}
}
}
}
With the animation set to finish in just 0.01 seconds, it happens so fast that you'll never even notice it as your bootup splash screen disappears and your MGSplitViewController view appears in its place. Maybe play around with it and make it instantaneous; I had to get it working and move onto my next task, so I didn't fool with it past that point.
I don't like resorting to hacks like this, but this was the only way I was able to get around this problem. ScottS' solution below sounded great, but unfortunately didn't work for me.

UINavigationController with presentModalViewController

I have a menu screen that implements UINavigationController and on top of that screen, using presentModalViewController, I place another screen on which I want to have another UINavigationController. I have tried to implement another navigation controller to handle the new screen but I either get a navbar 1/8th the way down the screen and it crashes or nothing at all. I have tried [[UINavigationController alloc] initWithRootViewController:navigationConroller] with no success as well. I'm just using pushViewController to try and place the next nib on the stack which doesn't work. What am I doing wrong?
Although there are a lot of people saying on forums that Apple doesn't allow this I have got it to work. What you have to do is:
Map *mapScreen = [[[Map alloc] init] autorelease];
mapScreen.delegate = self;
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:mapScreen] autorelease];
[self presentModalViewController:navController animated:YES];