Android - NestedFragments participate in populating the options menu - android-fragments

i am implementing the new nested fragment feature and had stumble into a problem.
my view is basically this:
a main activity(A) that includes a fragment(B), this fragment(B) includes a pager adapter that has 3 pages each of them is a fragment(C) also.
previously to the new getchildfragmentmanger this was not doable, but it works perfectly.
but one issue did arise, i want fragments C to be able to participate in populating the option menu.
i tired putting setHasOptionsMenu(true) in the onActivityCreated method on each of my C fragments and overriding also onCreateOptionsMenu but nothing happens...
if i try to populate the menu from fragment B (which is the container of the pager adapter) i can change the menu items...
any thoughts ?
Thanks.

Yes they can.
With android 4.2 or support library revisiion 11 nested fragments participate in populating options menu, as allways you need to call setHasOptionsMenu(true) during onCreate().
But if you are using ActionBarSherlock they won't, you have to manually call from parent fragment onCreateOptionsMenu() nested fragment method onCreateOptionsMenu().
Update: issue

From my read of the source code, it appears that the implementations of FragmentManager and Activity only work with the root FragmentManager for adding to the options menu/action bar, not and child FragmentManager instances.
Fragment B presumably will need to manage the options menu/action bar on behalf of the contents of the ViewPager, changing what is in the options menu/action bar based upon the pages being shown and hidden in the pager.

Related

How to disable the context menu of a QDockWidget title bar

I have a couple of QDockWidgets that are all not closabale (using Qt 5.6). Therefore, the context menu that is displayed when right-clicking a title bar of one of them only has disabled entries, and I would like to disable the whole context menu.
I tried to set the contextMenuPolicy to NoContextMenu without success.
I then tried to use a subclass of QDockWidget, override the ContextMenuEvent and ignore it. The menu is still displayed.
I then tried to install an event filter to catch the ContextMenuEvent, but it did not catch any, just PaintEvents, ResizeEvents etc.
I'm out of ideas … any help would be greatly appreciated!
As per the comments it is necessary to set the context menu policy on the QDockWidget to Qt::PreventContextMenu...
dock_widget->setContextMenuPolicy(Qt::PreventContextMenu);
rather than simply Qt::NoContextMenu. From the documentation Qt::NoContextMenu simply defers the context menu handling to the parent widget rather than preventing it entirely.

Editing the navigation controller from push segue

So i have a static tableview with 4 rows, i'm connecting them to different viewcontrollers without using any code instead i'm simply dragging the cell and setting up the segue.
The issue i'm having is that when this segue is performed a navigation controller is automatically generated and embed at the top so i get the following result below.
How could i edit the text and the icon? I want to remove the settings text and use my own custom icon.
It's also worth noting that i have embed other navigation controllers throughout my app. So i'd like to target this view specifically rather than all of my views.
I suspect the accepted answer on this question may help: how to replace/customize back button image in storyboard navigationcontroller
You'll need to do it in your prepareForSegue I believe.

How to Uninstall a UIView programmatically

In Interface builder the power of size classes lets you install constraints or uninstall them. In code you can do something similar by toggling the active property.
Interface Builder also lets you install or uninstall views. However, I would like to be able to do this programatically. UIView doesn't appear to have an active property. Is there any way I can uninstall a view programmatically? I'm looking for something where I can simply toggle a boolean property and the view and its constraints go into a dormant state and the view is no longer visible ands its constraints are no longer constraining until it is toggled to be non-dormant and then the view and the constraints work again.
Is this possible? Any workarounds?
A view's hidden property does not equate to the view being installed or not. From the Apple documentation on Installing and Uninstalling Views for a Size Class:
A runtime object for an uninstalled view is still created. However,
the view and any related constraints are not added to the view
hierarchy and the view has a superview property of nil. This is
different from being hidden. A hidden view is in the view hierarchy
along as are any related constraints.
So it sounds like the equivalent in code is something like:
// "Uninstall" the view from the superview
[self.myView removeFromSuperView];
// And add it back in
[self.view addSubview:self.myView]
You'd still have the view in memory, though not hidden. However you go about this I'm guessing your activating and deactivating constraints as this view comes and goes (unless the view itself is overlaying other things on the screen and not requiring a rearrangement of objects).

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.

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