UIBarButtonItem не будет отображаться при программной передаче - PullRequest
1 голос
/ 19 февраля 2020

Я создаю приложение, в котором программно использую ViewControllerA, потому что это список пунктов меню, каждый из которых приводит к разному V C, поэтому вместо нескольких сегментов я создаю экземпляр контроллера представления в коде. Моя проблема в том, что, хотя у меня есть элемент кнопки «Панель» на раскадровке, он не будет отображаться в приложении.

Просмотр контроллера Код модели меню:

class PlayerMenu: Hashable {
       let title: String
       let numberOfItems: String
       let menuItemViewController: UIViewController.Type?

       init(title: String, numberOfItems: String, viewController: UIViewController.Type? = nil) {
           self.title = title
           self.numberOfItems = numberOfItems
           self.menuItemViewController = viewController
       }

       func hash(into hasher: inout Hasher) {
           hasher.combine(identifier)
       }

       static func == (lhs: PlayerMenu, rhs: PlayerMenu) -> Bool {
           return lhs.identifier == rhs.identifier
       }
       private let identifier = UUID()

   }

ViewController A Код

 private lazy var menuItems: [PlayerMenu] = {
        return [
            PlayerMenu(title: "Status", numberOfItems: "Available.", viewController: nil),
            PlayerMenu(title: "Pertinent Medical History", numberOfItems: "", viewController: nil),
            PlayerMenu(title: "Injury / Illness", numberOfItems: "There are no injuries.", viewController: nil),
            PlayerMenu(title: "Allergy", numberOfItems: "There are no allergies.", viewController: AllergyTableViewController.self),
            PlayerMenu(title: "Neurocognitive", numberOfItems: "Unavailable.", viewController: nil),
            PlayerMenu(title: "Medication", numberOfItems: "There are no medications.", viewController: nil),
            PlayerMenu(title: "Immunization", numberOfItems: "There are no immunizations", viewController: nil),
            PlayerMenu(title: "Dictations", numberOfItems: "There are no dictations.", viewController: nil),
            PlayerMenu(title: "Imaging",  numberOfItems: "There is no imaging.", viewController: nil),
            PlayerMenu(title: "Participation", numberOfItems: "Unavailable.", viewController: nil),
            PlayerMenu(title: "Away Game Injury", numberOfItems: "Unavailable.", viewController: nil),

        ]
    }()

ViewControllerA Segue

extension PlayerDashboardViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let menuItem = self.dataSource.itemIdentifier(for: indexPath) else { return }
        if let viewController = menuItem.menuItemViewController {
            let navController = UINavigationController(rootViewController: viewController.init())
            present(navController, animated: true)
        }
    }
}

Снимок экрана раскадровки enter image description here

1 Ответ

1 голос
/ 19 февраля 2020

Причина, по которой вы не видите свой контроллер представления в том виде, как вы его спроектировали в раскадровке, заключается в том, что вызов viewController.init() не создает экземпляр вашего контроллера представления из раскадровки. Вам нужно позвонить:

UIStoryboard.instantiateViewController(withIdentifier:)

или в качестве альтернативы (только для iOS 13 +):

UIStoryboard.instantiateViewController(identifier:creator:)

Я рекомендую вместо сохранения типа контроллера представления в своем классе PlayerMenu хранить идентификатор раскадровки контроллера представления, например, так:

class PlayerMenu: Hashable {
    let title: String
    let numberOfItems: String
    let menuItemViewControllerStoryboardIdentifier: String?

    init(title: String, numberOfItems: String, viewControllerStoryboardIdentifier: String? = nil) {
        self.title = title
        self.numberOfItems = numberOfItems
        self.menuItemViewControllerStoryboardIdentifier = viewControllerStoryboardIdentifier
    }

    [...]
}

Тогда, когда вы захотите создать экземпляр контроллера представления, получить ссылку на раскадровку (если она совпадает с раскадровкой текущего контроллера представления, вы можете просто сказать self.storyboard, в противном случае создайте раскадровку напрямую с помощью UIStoryboard.init(name:bundle:)):

extension PlayerDashboardViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let menuItem = self.dataSource.itemIdentifier(for: indexPath),
            let viewControllerStoryboardIdentifier = menuItem.menuItemViewControllerStoryboardIdentifier,
            let viewController = self.storyboard?.instantiateViewController(withIdentifier: viewControllerStoryboardIdentifier) else {
                return
        }

        let navController = UINavigationController(rootViewController: viewController)
        present(navController, animated: true)
    }
}

Затем убедитесь, что вы указали идентификаторы контроллеров представления в вашей раскадровке, и создайте такие элементы PlayerMenu, как это:

PlayerMenu(title: "Allergy", numberOfItems: "There are no allergies.", viewControllerStoryboardIdentifier: "AllergyTableViewController (or whatever identifier you give this in your storyboard)")
...