Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISplitView's MasterViewController and Navigation Issue

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.

enter image description here

enter image description here

like image 245
David Sanford Avatar asked Dec 29 '17 17:12

David Sanford


People also ask

What is the uisplitviewcontroller?

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.

How do I get the Master View Controller in Split View?

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.

What is a split view controller for iOS?

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 .

What is the relationship between Master View Controller and detail view controller?

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.


1 Answers

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
}

Storyboard Split To access blue call detailsNavController, to access red use navigationController.

like image 76
MichaelV Avatar answered Nov 05 '22 20:11

MichaelV