I am updating my existing app to include a SplitView for iPads.
I have it working with a UITabBar, but am having an issue with my masterViewController as it is generating a "duplicate" navigation bar that is covering my existing navigation items on all masterViewControllers (tabs), including searchBar on the search tab.
The code I have is:
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
let splitViewController = self.window!.rootViewController as! UISplitViewController
splitViewController.delegate = self
splitViewController.preferredPrimaryColumnWidthFraction = 0.33
splitViewController.minimumPrimaryColumnWidth = 375
splitViewController.preferredDisplayMode = .allVisible
return true
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
return true
}
The reason for having this in the AppDelegate is I saw an example where placing it hear will allow me not to require the code in each of the different Master Views (each tab). Have yet to test this as still working on the first master view.
Master View
override func viewDidLoad()
{
self.extendedLayoutIncludesOpaqueBars = true
self.navigationItem.hidesBackButton = true
// 3D Touch
if traitCollection.forceTouchCapability == .available {
registerForPreviewing(with: self as UIViewControllerPreviewingDelegate, sourceView: view)
ThreeDTouch = true
}
self.addSwitchVewButtonToNavigationBar()
self.addCategoryButtonToNavigationBar()
}
func addSwitchVewButtonToNavigationBar() {
let switchButton = UIButton(type: UIButtonType.custom)
let editImage = UIImage(named: "CollectionButton")?.withRenderingMode(.alwaysTemplate)
switchButton.setImage(editImage, for: .normal)
switchButton.addTarget(self, action: #selector(SpeciesViewController.onSwitchView), for: UIControlEvents.touchUpInside)
let switchButtonFinal = UIBarButtonItem(customView:switchButton)
self.navigationItem.rightBarButtonItem = switchButtonFinal
}
@IBAction func onSwitchView(_ sender: UIBarButtonItem)
{
AppDelegate.getAppState().isListViewSelected = false
let speciesColletion = storyboard?.instantiateViewController(withIdentifier: Resource.SpeciesCollectionStoryboard) as! SpeciesCollectionViewController
self.navigationController?.viewControllers = [speciesColletion]
}
Originally, the onSwitchViewButton was embedded using the IB, but did not work. This is the same system used for the addFavorite on the Detail View.
Apple has built a rather handy view controller just for us called UISplitViewController and it harks right back to the iPad’s lowly beginnings. In this UISplitViewController tutorial, you’ll learn all about how to tame it! Also, since iOS 8, the split view controller works on both iPad and iPhone.
A split view controller has an array property viewControllers which contains the master and detail view controllers. The master view controller, in your case, is actually a navigation controller. So to get the actual MasterViewController instance, you take the navigation controller’s first view controller.
You’ll use a split view controller to handle the navigation and display. It’ll adapt to work on both iPhone and iPad. Note: This tutorial focuses on split view controllers. You should already be familiar with the basics of creating an iOS app first, such as Auto Layout and storyboards .
In the Master-Detail App template, the master view controller has a reference to the detail view controller. That means the master view controller can set a property on the detail view controller when a row gets selected. That works fine for simple applications where you only have one view controller in the detail pane.
The problem that you addressing wrong UINavigation controller. I assume before splitting both master and SpeciesViewController existed in same navigation environment, and use same navigation controller. But in split view they don't. Your detail controller is actually UINavigation controller you are looking for, that had to control all navigation, and had to have buttons you need. You can get it from master as:
guard let split = splitViewController, let navController = split.viewControllers.last as? UINavigationController else { return }
And make sure that you split controller not embedded into another UINavigationController (reason for second navigation bar).
EDIT: Function to return detail's Nav Controller:
var detailsNavigationController: UINavigationController? {
return splitViewController?.viewControllers.last as? UINavigationController
}
To access blue call detailsNavController, to access red use navigationController.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With