Autorotate with a UINavigationController - uinavigationcontroller

I am a little unclear on how to rotate views that are sitting on a UINavigationController.
I have overridden the UINavigationController object with one of my own that overrides:
(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { return YES; }
I have one view on the stack on the controller and that view is loaded from a xib with two views in it. I want to switch from portrait to landscape. Normally I would handle this by changing the view from within the nib files of the view itself. Do I have to implement the rotational code within the Navigation Controller or just within my view code?
(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
That willAnimate code is what I'm used to using in the view itself, but I'm still not seeing the view being changed, and I'm thinking it may be that I need to access the view in the NavigationController and change that, or even override the same method in the Navigation Controller and do my view switching there.
Any suggestions? I've never actually done this before and just found out the TabViewControllers and NavigationControllers are both portrait mode only by default.

Turns out it wasn't possible to change the view because I was trying to changes the RootView on the Navigation Controller. I got around this by placing my own pseudo root view controller that never gets seen in the root spot on the Navigation stack. I overrode a few of the navigation controls to account for this so the functionality would continue the same and I'd be able to change my desired perceived root view as I needed to.
A start in the right direction can be found in this link:
http://starterstep.wordpress.com/2009/03/05/changing-a-uinavigationcontroller’s-root-view-controller/

Related

NavigationController and View Hierarchy issue

I have 1 (rootViewController) view controller which is embedded in navigation controller. Then i pushed another view controller (secondViewController), which has search controller in title view. When i am trying search become first responder (Active) i got this in terminal:
Warning: Attempt to present
"AppName.CustomSearchViewController: 0x7face0c20eb0> on
whose view is
not in the window hierarchy!
This happens only in iOS lower than 11. When i embed this second view controller in navigation controller and present it modally all works good, but i need exactly pushing. How can i solve this?
I solved it! I need to make definesPresentationContext false in rootViewController to make it work on another one!

NavigationController & hidesBarsOnSwipe with CollectionView subview

I'm pretty new to iOS development and I'm having some trouble with navigation controller and a collection view as a Subview.
Ive started my project with a single view application and embedded in a Navigation controller (The Navigation controller root is my ViewController).
Inside my view controller i've added a Collection view with a custom cell (it doesn't take the whole screen).
when I run my application everything works fine.
when I tried to set the method
navigationController?.hidesBarsOnSwipe = true
nothing happens inside my Collection view even though I'm scrolling, but if I swipe within the View controller and not the Collection view the method works and the Navigation bar gets hidden just fine.
I want the method to work when I swipe inside the Collection view.
Thank...
If your collection view top is set to the top layout guide top then the view behind is has never scrolled, i.e. your view isn't scrolling so the navigation bar is not hiding.
Try setting your collection view top to the "Top Layout Guide.Top". Try changing this to "Superview.Top".

UITabBarController in UISplitViewController with Storyboard

I have UISplitViewController with UITabBarController as its master. UITabBarController contains one UINavigationController with UITableViewController as its root (it is main menu of my app).
After tapping on any cell in main menu, in UISplitViewController's detail part another UITableViewController should be presented (let's call it detail view).
In landscape mode everything works OK.
But in portrait, whet I tap on cell in main menu, the detail view is presented modally, and not pushed, like it supposed to. Also, when rotating from landscape to portrait, the main menu is presented instead of detail view, and after I click on main menu's position to show detail view, it is presented modally with no possibility to rotate or to go back.
Removing UITabBarController and setting UINavigationController as UISplitViewController's master works as I want (in landscape mode we have menu|detail views side by side and in portrait mode controllers behave like they were on regular UINavigationController). But then the UITabBarController is gone.
What I've tried:
every possible segue type - none of them works the way I want
subclassing UIStoryboardSegue to implement custom behavior depending on UISplitViewController's viewControllers param (in portrait mode it has only one view controller - master) - but I couldn't recognise classes (thank you Swift!)
What I want is to do it entirely in Storyboard (OK, custom segues doesn't count) - I want an elegant solution and I refuse to believe it's impossible.
Working on iOS 8 SDK, Xcode 6.2, iPhone 6 Plus
Unfortunately there is no absolutely elegant solution to this one (as far as I've managed to accomplish). Hoping that Apple will eventually sort it out, but in the meantime, this is the nicest way possible:
Place one custom segue instead of Show Detail
In perform method of your custom segue have something like:
- (void)perform
{
MasterViewController *source = self.sourceViewController;
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
UISplitViewController *splitViewController = appDelegate.splitViewController;
if ([splitViewController.viewControllers count] > 1) {
[source performSegueWithIdentifier:#"showDetail" sender:source];
if (appDelegate.masterPopoverController) {
[appDelegate.masterPopoverController dismissPopoverAnimated:YES];
}
} else {
[source performSegueWithIdentifier:#"showDetailSmallDevice" sender:source];
}
}
[splitViewController.viewControllers count] is here just to separate large devices (iPads & iPhone 6 Plus) and the other, smaller ones
In your Storyboard, wire up one segue named showDetail which is actually a showDetail, to the detail navigation controller, and directly to the contents view controller another showDetailSmallDevice which is actually Show
(Push)
See the example:
http://i.stack.imgur.com/GQpg3.png
EDIT: SplitViewController needs two Navigation Controllers. The solution is that you need to insert another Navigation Controller between the SplitViewController and the DatailViewController. Then, from the TableView, preform a Segue directly to the second Navigation Controller. The SplitViewControllers wants two Navigation Controllers...
Maybe a good way could be to start a new SplitViewController project on IB. There are various default methods and properties to manage a SplitViewController. You can find something in appDelegate class, it could be a good starting point.
OLD: I like Mateusz's answer, just a point that is possible to use self.splitViewController.isCollapsed for testing if DetailViewController is or it could be shown on screen. With this property there is no need to count viewControllers.
#property(nonatomic, readonly, getter=isCollapsed) BOOL collapsed
From documentation: A Boolean value indicating whether only one of the child view controllers is displayed. This property is set to YES when the split view controller content is semantically collapsed into a single container. Collapsing happens when the split view controller transitions from a horizontally regular to a horizontally compact environment. After it has been collapsed, the split view controller reports having only one child view controller in its viewControllers property.

Combining a navigationcontroller and a root view controller with pages

I have a problem that has been solved on iOS6, but still appears if I use the iOS 5.1 simulator.
I have a default page based application. I added a "Main menu" view controller, that has three buttons that activate the root view controller containing the pages via a push segue, all defined in the storyboard.
I then added a navigation controller and made it the initial view controller.
If I pas the menu via a button and flip a few pages I can click the back button and it goes back to the menu. Good.
But I don't want the nav bar, so I hide it, and on the root view controller that contains the page view controllers I add a button which performs this action:
[self.navigationController popToRootViewControllerAnimated:YES];
This button works perfect on iOS6, I can flip a few pages, press the button and I'm back in the menu.
With the iOS 5.1 simulator however (and on my 5.1 iPad), a page flip occurs! It's a page filp until I'm on the last page and then I go back to the menu.
I searched for over two hours now but could not find a solution, I hope someone can help me with this?
Note: setting animated to NO does not solve the problem.
I did find the answer to my question, this is my first iOS project which explains why I did not find it any sooner myself.
In the default page based application there are two lines in the viewDidLoad method:
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
First, it's not really adding but assigning that happens here, second, when I put the second line in comment, everything works as expected.
So I'm glad it solves my problem, however it raises some questions:
The gestures are started as easy as they were, so why was this line needed in the first place, what does it supposedly fix?
Why does it work in iOS6? It should have had the same problem, no?
Is it correct that it is an assignment and not an addition?
Any answers to these three are still appreciated.
Alex

UINavigationController change position of pushed UIViewController view

I tried to solve this in so many ways but always failed.
Basically what I need is a NavigationController with a customized NavigationBar (different height and smaller back Button) which I already achieved.
This creats two problems. If I use the default NavigationBar of the NavigationController, I have a smaller NavigationBar but the views of the pushed ViewControllers still position as if the NavBar would have the usual height. If on the other hand I use my a self created NavBar and hide the default one, then the views of the pushed ViewControllers position as if I wouldn't have any NavBar at all. I don't know where to set the views frame. No matter where I try to set them, it doesn't work.
Is there any strategy without implementing an own NavigationController from scratch?
Not using nib files, dev for iphone OS 4.0 but will switch back to iphone OS 3 quite soon again.
Try using your own customized Navigation controller and setting the frame of the pushed view in its ViewWillAppear method.
Hiding the usual Navigation Controller will create problems. Its better NOT to use it completely if you do not intend to use it . But after doing that , you will have to use your customized Navigation controller in the project wheresoever.

Resources