UIPopoverController in SplitViewController - iphone

I have a fairly complicated issue which I will describe as good as possible.
I have an iPad App and a SplitviewController as my main view. In Portrait mode, the SplitviewController hides the Tableview to the left, so that the DetailviewController is visible only. So far so good.
The way you use this, is, from what I understand, that if I tap on a cell to the left, I replace the Detailview to the right with a new view I want to show. To this end, I use the viewControllers property.
Now to display the Popover I have a Toolbar at the top and a Menu Button to display the Popover.
Here's the thing:
I tap on a cell, and replace the DetailviewController with a new Viewcontroller. But now the Popovercontroller is gone, since it was declared in the header of the old ViewController.
The problem: When I tap on the Menu Button in port mode, the popover cant be displayed, since it is nil now, as it wasnt initiated yet.
But what I can do is: I rotate the iPad to the landscape, and rotate it back again. The popover is back, bacause in the delegate method of the splitviewcontroller the following happens:
- (void) splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc {
self.popoverController = pc;
}
Where does this pc come from? How can I do that myself.
If I try to re-alloc the Popovercontroller this breaks the SplitviewController and artifacts in the App appear.
I hope I explained my problem well enough.
Any ideas?

Take a look at this sample code from Apple:
http://developer.apple.com/library/ios/samplecode/MultipleDetailViews/Introduction/Intro.html
It demonstrates how to switch between different detail views by tapping on items in the table in the split view app's lefthand view.

Related

Pushed ViewController is "greyed out" cannot intact with it

Im relatively new to iOS programming and have been making a recipe based app for the iPad. I've looked around at a lot of answers and can't seem to solve my problem so ill explain how my app is laid out.
Navigation controller -> ViewController -Modal segue -> PreviewViewController -modal segue -> Navigation Controller -> RecipeViewController
Within my RecipeViewController i have a button that when pressed i want it to go back to the "home" screen which for these purposes is the "ViewController".
Here is the code for the button action in "RecipeViewController":
- (IBAction)homeB:(id)sender {
ViewController* viewController = [[ViewController alloc]init];
[self.navigationController pushViewController:viewController animated:YES];
}
However, when i press this button the ViewController is displayed, but the screen is greyed out and i can have no interaction with the screen. I can't post an image of what the screen looks like as i don't have enough reputation yet but i will update it when i can.
I have tried other ways of displaying it such as connecting a segue in the storyboard between the button and the "ViewController" and then activating the segue when the button is pressed. But this messes up other parts of my code as i have to re allocate and initialise the home screen. Would appreciate any help as to why it is coming up with the greyed out screen that cannot be interacted with.
Also just some more notes:
self.navigationController
does not return nil so it is seen, and no errors are displayed when the button is pressed.
Thanks
If you're really doing segues, then I presume this was made in a storyboard. If that's the case, then you should use an unwind segue to get back to ViewController. You do this by adding an IBAction in ViewController that looks like this:
-(IBAction)comingBackFromRecipe:(UIStoryboardSegue*)sender {
NSLog(#"I'm back");
}
The important point is that the sender type be UIStoryboardSegue. Then in IB, in the RecipeViewController, you control drag from your button to the green "Exit" icon at the bottom of the controller. When you let go, you should see the method that you wrote in ViewController -- connect it to that. This will get you back to the same instance of ViewController that you started with.
It's hard to tell without seeing a screenshot, but from what i understand, if you want to go back to the home screen, you shouldn't be pushing a new view controller (unless you really want to add it to the stack?)
To go back to the "home" screen, you should try this:
[self.navigationController popToViewController:viewController animated:YES];
or if your home screen is the root, simply use this:
[self.navigationController popToRootViewControllerAnimated:YES];
Thanks for the responses everyone, i figured out my problem though. My structure was wrong and i realised that i didn't need to have another navigation controller for the Recipe view Controller as i wasn't pushing anywhere from there. So incase anyone else has a similar problem my structure is now as follows:
Navigation Controller -> View Controller -Modal Segue -> PreviewViewController - ModalSegue -> RecipeViewController
I removed the Navigation controller between PreviewViewController and RecipeViewController. This means that they are all modal view controllers. So to get back from the RecipeViewController to the home screen which is "ViewController" i just needed to dismiss the hierarchy of modal views with the following code:
UIViewController * parent = self.presentingViewController;
[parent.presentingViewController dismissViewControllerAnimated:YES completion:nil];
I went back two stages so that both the PreviewViewController and the RecipeViewController where dismissed.
Works great now, thanks for the help anyway everyone.

UINavigationController TitleView not displayed from ViewController NavigationItem

Whenever I add a viewController to a navigationController while in landscape the title view appears on certain views but not on others. ie: I have a navigation controller, add 3 view controllers, first two show titleview appropriately, third one doesn't show one at all. But the navigation controller grabs the titleview from the ViewController like it's supposed to, I wrote the value of it to the console and it is correct, but it just doesn't show on the screen for whatever reason. Any ideas?
Oh yeah works perfectly while in portrait orientation.
Here's another fun part, if I push the trouble view controller into the navigationController in landscape the titleView isn't there, then without any user interaction, I rotate the device back to portrait and the titleView appears, then I rotate the device back to landscape and it stays!
It's like the drawing of my TitleView was blocked even though I used InvokeOnMainThread. Nothing is running in the main thread (or anywhere for that matter) during that call.
Here's my structure:
Window
TabBarController
NavigationController
ViewController
NavigationController
ViewController
Here's my order of operations:
Create View Controller
Add Title view to view controller
Push View Controller onto NavigationController (InvokeOnMainThread)
Have you tried setting the controller title after the controller is pushed? This kind of behavior happens to me and the way to make sure the title appears is to mandatory set the navBar title in the viewDidLoad or viewWillAppear method as follows:
self.navigationController.navigationBar.topItem.title = #"The title";
or
self.navigationItem.title = #"The Title";
Other thing that happened to me is to set the leftBarButton or RightBarButton of a navigation bar without success in the viewDidLoad method, but they appear correctly when setting the bar buttons in the viewWillAppear method.
Hope this helps.
I think your problem maybe that when your function is called, the navigation item is nil. So when you call self.navigationITem.title, it do nothing. Later, when the view is rotated, the navigationItem is not nil anymore so changing the title works.
If you do the code in ViewDidLoad function beware that ViewDidLoad is called the first time someone calls viewController.view and not the first time the view is displayed. So the view may not be in a navigationController yet.
For example, this can happend if you do :
viewController.view.backgroundColor = ... ;
[navigationController pushViewController:viewController]
The first line will call ViewDidLoad even if the controller is not in a navigationController yet.

Getting empty view and blank navigation bar when I use popViewControllerAnimated

I'm writing an iPhone app that is based on a UINavigationController. I'm pulling data from a server that sometime returns bogus links. I open each link by pushing a webview viewcontroller. I want to be able to include some error handling. I know if the link is no good. So I want to be able to pop the webview view controller as soon as I know that my webview has encountered an error.
Currently, I've tried using the following code:
[self.navigationController popViewControllerAnimated:YES];
I then get a Navigation bar with nothing displayed in it, but if I click where the "back" button should be it operates appropriately. The title pops up when I click where the "back" button should be. The view where the viewcontrollers usually display there content is blank white too even though I'm popping back to a UITableViewController.
I've tried this as a workaround:
UINavigationController *nav = self.navigationController;
[self.navigationController popViewControllerAnimated:YES];
[nav.visibleViewController.view setNeedsDisplay];
I've checked the viewControllers array in the UINavigationController and it has the right viewcontrollers in it (ie it has removed the viewcontroller for the webview).
I also tried putting code in the viewWillAppear of the viewcontroller I'm popping back to, but the method is never getting called.
I'm looking for a way to force the UINavigationController to reload the same way that you can call reloadData on a UITableView.
Any help would be greatly appreciated.
I saw something like this on my app where I was using a navigation bar I added in Interface Builder on the root view of a navigation controller and then programmatically creating the nav bar and its subviews for the second view. When I would pop the second view to return to the first view I would hide the self.navigationcontroller bar which would show the white space underneath until the IB nav bar of the previous view appeared. To fix this I decided to stick with programmatically creating all my navbars which fixed the issue for me.
TL;DR - if you are using both IB and programmatically made navbars this can happen when popping views, stick with one or the other for all the navbars yo

selectively allowing autorotation in TabBar / UINavigation app

I have a UITabBar/UINavigation application and I'm having some trouble allowing autorotation in a given view.
The TabBar allows changing sections, with table view items. When one of the items is tapped, I push a new view which hides the TabBar and which should autorotate. I tried the easy way, which seemed most logical to me: disable autorotate in the rootViewController and allow in the detailViewController, but this didn't work (shouldAutorotateToInterfaceOrientation returns YES, but then willRotateToInterfaceOrientation is never called and view doesn't autorotate). I read that all VCs in a TabBar should return YES to shouldAutorotateToInterfaceOrientation, so I did that, but the result is that now my whole application rotates.
I then subclassed my UINavigationController and set shouldAutorotate to NO, hoping that I could detect when the view that was being shown was in fact a detailView, and then return YES... I can't seem to do that.
Any help out there?
Thanks!
Antonio
It sounds like you've got a set up like the iPod app which has a tabbar for playlist view, songs view etc but which disappears when you go to a detail view for a song. The detail view can rotate but the tabbar views do not. When you do rotate the tabbar it turns into a cover flow detail view.
I'm pretty sure they do this by putting the tabbar inside a navigation controller. When you go to the detail view, it pops the tabbar entirely and pushes the detail view.
So the actual hierarchy looks something like:
Nav {
tabbar {
playlist
Artist
//... other tabs
}
detail view portrait
detail view cover flow
}
Only one of the sibling views (tabbar, detail portrait, detail coverflow) is pushed at any one time.
The iPod app does this because the detail view is the primary functional view for the entire app so the rest of the app is built around navigating to it. If that is not the case for your app, then this setup may be more trouble than it is worth.

Displaying UIImagePickerController within another UIView

I've been working pretty extensively the last couple months with UIImagePickerController, particularly with the new capabilities in OS3.1 and newer to overlay views on-top of the camera view. This has worked just fine.
However, I am currently working on a project where I'd like to be able to display the camera view of the UIImagePickerController within an existing view. Essentially, the exact opposite of what I've currently been doing.
An example would be a View Controller with navigation components (Think top and bottom horizontal bars with gradients), and upon tapping a button on one of these bars, then content area displays the camera view. The shutter animation would should up, and the top and bottom navigation bars would remain always on-top.
I've had success adding the UIImagePickerController to the window view, as well as presenting it modally, but haven't had any luck adding it as a subView.
ex:
[window addSubview:camera.view];
[self presentModalViewController:camera animated:YES];
All you need to do is call viewWillAppear and viewDidAppear.
Here is an example where _pickerController is an instance of UIImagePickerController:
[self.view addSubview:_pickerController.view];
[_pickerController viewWillAppear:YES];
[_pickerController viewDidAppear:YES];
Call viewWillAppear:YES on the image picker controller after adding its view to your view. Skip the modal view controller business.
I don't think the API provides direct access to the actual view of the UIImagePickerController. The class is actually a subclass of UINavigationController so I don't think it has an actual view itself but rather manages the calling of its subcontrollers and their views.
When you call the UIImagePickerController modally, its doesn't add the views it controls as subviews to the window (or any other view). That is what a modal view means. It presents the view off to the "side" of the view hierarchy.
Even if you could hack this together, I think Apple would reject it as not being part of the API and for violating the HIG.