Reputation: 3545
Does someone know a way to change the text (and appearance?) of the button returned from the UISplitViewController delegate:
func displayModeButtonItem() -> UIBarButtonItem?
Upvotes: 17
Views: 8154
Reputation: 51
I have this exact same issue.
This is how I'm going to solve it, I'll update on my results.
The UIBarButtonItem
returned by displayModeButtonItem
is managed by UISplitViewController
in it's own good time. So any changes you make are blocked.
However there is a new delegate function:
- (UISplitViewControllerDisplayMode)targetDisplayModeForActionInSplitViewController:(UISplitViewController *)svc
I am going to create my own UIBarButtonItem
that will change based on when this function fires.
I will then get it to trigger the display mode as appropriate.
Upvotes: 1
Reputation: 57
I wanted to update this with the proper solution to showing a title in the displayModeButtonItem. This method shows the back arrow, as well as the proper text. Most of the above solutions do not include the back arrow in the end, from what I could tell. I had tried setting this a few different ways, but it always got wiped when the master view would open and close again (iPad Portrait), only leaving me with the back arrow.
You must set the "Title" property on the Master View's navigationController.
Note that this is different from setting the Back and Title texts on the master view's navigation item. Setting on the Navigation Item WILL NOT work.
Upvotes: 3
Reputation: 634
This text is set by setting the "Back Button" text property of the Navigation Item in the Master View Controller through Interface Builder
Upvotes: 2
Reputation: 662
I tried EmilDo's solution, but the navigation button was not shown. I changed the solution a little bit and got it working with the following code:
DetailViewController:
override func viewDidLayoutSubviews() {
if splitViewController!.displayMode == UISplitViewControllerDisplayMode.PrimaryHidden || splitViewController!.displayMode == UISplitViewControllerDisplayMode.PrimaryOverlay {
let displayModeButton = splitViewController!.displayModeButtonItem()
let searchButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: displayModeButton.target, action: displayModeButton.action)
navigationItem.leftBarButtonItem = searchButton
} else {
navigationItem.leftBarButtonItem = nil
}
}
SplitViewController:
func splitViewController(svc: UISplitViewController, willChangeToDisplayMode displayMode: UISplitViewControllerDisplayMode) {
svc.view.setNeedsLayout()
}
Upvotes: 2
Reputation: 554
The problem with all the above solutions is that the back button image is not displayed, at least not in my project where I tried to create my own custom bar button item. When using the UISplitViewController displayModeButtonItem and setting the master view controller left bar button item to supplement the back button item (controller.navigationItem.leftItemsSupplementBackButton = YES), the little < symbol appears before the left bar button item title. With a custom one, it doesn't.
Upvotes: 0
Reputation: 1177
doing that in targetDisplay does the trick but removal/addition of the button is visible at the end of the rotation, it is better to do that in splitViewController:willChangeToDisplayMode:displayMode but keep in mind that this should also be handled on viewDidLoad too since that delegate method is not called at startup.
- (void)splitViewController:(UISplitViewController *)svc willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode
{
if (displayMode == UISplitViewControllerDisplayModePrimaryHidden || displayMode == UISplitViewControllerDisplayModePrimaryOverlay) {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Lista" style:UIBarButtonItemStylePlain target:self.splitViewController.displayModeButtonItem.target action:self.splitViewController.displayModeButtonItem.action];
} else {
self.navigationItem.leftBarButtonItem = nil;
}
}
Upvotes: 4
Reputation: 723
I made a combination of josh's and voluntas88's solutions on my solution.
First you need to use the UISplitViewControllerDelegate
method
func targetDisplayModeForActionInSplitViewController(_ svc: UISplitViewController) -> UISplitViewControllerDisplayMode
and then add a customized UIBarButtonItem. Here is my solution:
func targetDisplayModeForActionInSplitViewController(svc: UISplitViewController) -> UISplitViewControllerDisplayMode {
if svc.displayMode == UISplitViewControllerDisplayMode.PrimaryHidden || svc.displayMode == UISplitViewControllerDisplayMode.PrimaryOverlay {
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named:"menu.png"),
landscapeImagePhone: UIImage(named:"menu.png"),
style: UIBarButtonItemStyle.Plain,
target: self.splitViewController!.displayModeButtonItem().target,
action: self.splitViewController!.displayModeButtonItem().action)
}else {
// disable button on landscape
if UIApplication.sharedApplication().statusBarOrientation == UIInterfaceOrientation.LandscapeLeft || UIApplication.sharedApplication().statusBarOrientation == UIInterfaceOrientation.LandscapeRight {
self.navigationItem.leftBarButtonItem?.enabled = false
}
}
return UISplitViewControllerDisplayMode.Automatic
}
Upvotes: 5
Reputation: 4583
So i was looking for a way to implement a custom button on my UISplitViewController, the button that shows the RootViewController (the side drawer or overlay, whatever its called). I came to this page and the question is to change the button that is being sent from the UISplitViewControllerDelegate. It appears that there is no call that you can implement in that delegate but you can just set the button to be a custom bar button item
On the DetailViewController, the nondrawer, overlay view, you just need to declare it and point the action and target of your custom button to be the same as what the UISplitViewController's button is
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self.splitViewController!.displayModeButtonItem().target, action: self.splitViewController!.displayModeButtonItem().action)
Upvotes: 0
Reputation: 241
I resolved it for myself in such way:
UIBarButtonItem(image: UIImage(named:"home"),
landscapeImagePhone: UIImage(named:"home"),
style: UIBarButtonItemStyle.Plain,
target: splitViewController.displayModeButtonItem().target,
action: splitViewController.displayModeButtonItem().action)
I use this in AppDelegate instead of splitViewController.displayModeButtonItem()
and it works fine for me.
Upvotes: 21