NavigationController & hidesBarsOnSwipe with CollectionView subview - uinavigationcontroller

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".

Related

UINavigationController and large titles when popping ViewController

I have a UINavigationController which has its navigationBar configured to prefersLargeTitles = true and isTranslucent = false.
The first view controller in the navigation stack is a UITableViewVontroller with its navigationItem configured as largeTitleDisplayMode = .always. If I push a further view controller with largeTitleDisplayMode = .never and pop it again, the first view controller is in a state where the large title is collapsed. I have to scroll up to enlarge the title again.
Is this intentional behaviour of iOS 14? Is there a way to restore the large title?
Edit: I just realized, that the behaviour is tied to the isTranslucent property of the navigation bar.

UISplitViewController - Unbalanced calls to begin/end appearance transitions

I am using the new UISplitViewController for ios8 that has preferred display modes. My master split view is a UITabBarController with a UINavigationController inside it. I disabled the presentsWithSwipe gesture, and instead have a button in my detail view controller that toggles the splitviewcontroller between 2 preferred display mode states: UISplitViewControllerDisplayModeAllVisible and UISplitViewControllerDisplayModePrimaryHidden.
When I toggle the button so that both view controllers are visible, I can see my navigation controller display it's tableview controller. However, when I click on a cell in my tableviewcontroller that performs a storyboard segue to another view controller, I get the following error:
Unbalanced calls to begin/end appearance transitions for <ReferenceTableViewController: 0x7fde50540d50>
My set up is
SplitMasterViewController --> UITabBarController --> UINavigationController --> ReferenceTableViewController --> ReferenceDetailViewController
SplitDetailViewController --> UINavigationController --> MainViewController
Basically, I want to animate in/out the master view controller which provides information relevant to the MainViewController. Actions taken in the MasterViewController do not replace out the DetailViewController, but rather should navigate within the MasterViewController frame. Kind of like having an iPhone side by side with a smaller iPad, with independent content in each.
However, I'm not getting any of the view appearance methods being called in the ReferenceTableViewController or the RefernenceDetailViewController. I always call super if I override any appearance methods, so I'm not sure where the error is coming from. Any ideas?

Substitution of detail view controller does not cause viewWillAppear to be called

I'm porting my iPhone app to iPad. On iPhone I select row in the table, and after that the next view controller is pushed to the top of navigationController (now navigation is performed on the left part of split view controller). For iPad i modified the code this way:
if (deviceIsIPad())
{
UISplitViewController *svc = (UISplitViewController *)[self findNearestParentOfClass:[UISplitViewController class]];
svc.viewControllers = [NSArray arrayWithObjects:[svc.viewControllers objectAtIndex:0],
nextViewController,
nil];
}
else
[self.navigationController pushViewController:nextViewController animated:YES];
There are no problem at iPhone code (when controller is pushed to navigation controller), but on iPad viewWillAppear: is not called (viewDidLoad is called however), while I have a reason to perform some customization right in viewWillAppear:. Why is it not called, and what should I do to force it to be called?
Much thanks in advance!
Not exactly sure what you're trying to do here but simply initializing a splitview controller and adding controllers to it does not force views to appear. You have to add the splitview controller's views to the window.
Here is the code from the Xcode Splitview template's app delegate's applicationDidFinishLaunching:
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
splitViewController.delegate = detailViewController;
NSLog(#"master=%#",splitViewController.viewControllers);
// Add the split view controller's view to the window and display.
[window addSubview:splitViewController.view];
[window makeKeyAndVisible];
The views in the navigation controller appear because it is already attached to the window and displaying the view of one of its controlled controllers.
Edit:
From Comments:
All initialization code you are quoted
here is already performed. Now, let's
assume one have a table on the left
controller, then he select another row
there, and want to replace right
controller with another one.
splitViewController.view is added on
the window фдкуфвн, because some GUI
elements initialized in viewDidLoad,
are properly presented on view
It sounds like your problem arises because the detail (right-side) view of a splitview controller is always visible i.e. it only appears i.e calls viewWillAppear, once immediately after first being loaded. There is no point at which the detail side has no view present. I'm not sure what entirely swapping out viewControllers of the splitview will do.
If you want to change the detail view on the fly. You need to put a navigation controller in the right side and then push and pop view-controllers in that nav in response to events in the right side controller.
Look at how the iPad iPod app works. You have a leftside view of playlist and on the right side, a list of all the songs in the playlist. Selecting a song pushes a song detail view on top the list of songs.

UIBarButtonItems not showing up on UIToolbar

I have a UINavigationController with toolbarHidden set to NO.
I have added UIBarButtonItems to navigationController.toolbar.
The toolbar is displayed, but the buttons are not...
What gives?
Ok so apparently I misunderstood the usage of the setItems method on navigationController.
To remedy this I set the toolbar items on each view controller that is pushed onto the navigation controller's stack.
I guess if I wanted to have one toolbar persist through all the views I could add a new toolbar to the view controller holding my navigation controller then simply invoke setItems on my navigation controller.
I digress.

Autorotate with a 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/

Resources