更改从代码初始化的视图控制器时如何修复消失的选项卡栏控制器

How to fix disappearing Tab Bar Controller when changing View Controller initialized from code

我正在努力解决这个问题,当我切换与 push segue 连接的视图控制器时,一切都按预期工作。问题是我有一个从代码执行 Table View Controller 的搜索栏,当我 select 来自那个 Table View Controller 的单元格时,下一个 View Controller 没有标签栏。

我正在使用 Table 视图控制器作为显示搜索栏结果的视图。当我 selecting 单元格(搜索结果)时,我正在更改显示结果的视图控制器。但是这个是从故事板完成的。 我知道从代码执行的 Table View Controller 不会通过导航栏从以前的控制器 "inherits" 选项卡栏。但是这个应该从代码中执行。

Initialize Search Result Controller
 override func viewDidLoad() {
    super.viewDidLoad()
    self.definesPresentationContext = true

    tableView.separatorStyle = .none
    self.extendedLayoutIncludesOpaqueBars = true
    refreshControlUI = Refresher.configureRefresher()
    tableView.refreshControl = refreshControlUI
    refreshControlUI.addTarget(self, action: #selector(pullToRefresh), for: .valueChanged)


    // Initialize search table
    let priceSearchTable = storyboard?.instantiateViewController(withIdentifier: "CoinSearchTable") as! CoinSearchTableViewController

    // asignle pricetable as a search results controller
    resultSearchController = UISearchController(searchResultsController: priceSearchTable)
    resultSearchController?.searchResultsUpdater = priceSearchTable

    // Make navigation bar large
    self.navigationController?.navigationBar.prefersLargeTitles = true
    self.navigationController?.navigationItem.largeTitleDisplayMode = .never
    self.navigationItem.searchController = resultSearchController

    // customize search bar
    let searchBar = resultSearchController!.searchBar
    searchBar.sizeToFit()
    searchBar.placeholder = "Search for coins"

    resultSearchController?.hidesNavigationBarDuringPresentation = false
    resultSearchController?.dimsBackgroundDuringPresentation = true


 }
This code is responsible just for passing values to selected view controller.
 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if shownAllCoins.count > 0 {

            let coinString = shownAllCoins[indexPath.row]
            picked = PickedCoin(symbols: [coinString])
            picked.delegate = self
            navigationController?.setNavigationBarHidden(false, animated: true)
            picked.getDetail(name: coinString)
            coin = picked.coins[0]
    }

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "goToDetailsFromSearch" {
        if let coin = sender as? [Any]{
            if let SearchVC = segue.destination as? DetailPriceViewController{

                SearchVC.coin = coin[0] as? Coin
                SearchVC.isFromSearching = coin[1] as! Bool
            }
        }

    }
}

此外,在详细视图控制器中,我必须以编程方式创建导航栏,以防转场来自搜索结果控制器。

func addNavBar() {

        view.backgroundColor = UIColor(hex: 0x001f3e)

        let navBar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 20, width: view.frame.size.width, height: 44))
        navBar.barTintColor = UIColor(hex: 0x001f3e)
        navBar.isTranslucent = false
        self.view.addSubview(navBar);
        guard let coin = coin else {return}
        let navItem = UINavigationItem(title: "\(coin.symbol)")

        let backButton = UIButton(type: .custom)
        let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
        navBar.titleTextAttributes = textAttributes

        saveButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.bookmarks, target: self, action: #selector(self.selectorName(_ :)));


        backButton.setTitle("Back", for: .normal)
        backButton.setTitleColor(backButton.tintColor, for: .normal) // You can change the TitleColor
        backButton.addTarget(self, action: #selector(self.backAction(_:)), for: .touchUpInside)

        navItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
        navItem.rightBarButtonItem = saveButton

        navBar.setItems([navItem], animated: false)
    }

下面是故事板连接的屏幕截图。这个没有导航栏的storyboard当然就是这个SearchResultController(Table显示结果并切换到detail controller的View Controller)

将选项卡栏设置为根控制器或其他东西的最佳方法是什么。我只需要标签栏出现在所有视图控制器中,而不管控制器是从故事板还是代码初始化的。

我整天都在尝试解决这个问题,但我不知道如何.. 感谢您的帮助!

谢谢!

好的,问题出在 segues 上。我试图从另一个 Controller 传递值,它与前一个 Controller 没有任何共同之处,因此很明显导航栏和选项卡栏不存在。在处理单独的可搜索视图控制器时,应该添加委托,将值传递回主控制器。当与可搜索视图控制器交互时,在我的例子中将值传递给另一个视图控制器的过程如下所示:

  1. 当我开始在主控制器上打字时,新的可搜索视图控制器出现
  2. 当我找到我需要的项目时,我通过 didSelectedRowAt 选择它
  3. 我正在通过委托函数传递选定的值
  4. 向主控制器添加委托,从那里应该完成 segue

现在一切正常。

简单的代码如下所示:

protocol SearchTableDelegate {
func passSelectedValue(selected stock: String) 
}

在可搜索视图控制器中声明:

var delegate: SearchTableDelegate!

在 DidSelectedRowAt 中:

delegate.passSelectedValue(selected: selectedValue)

现在在主控制器中:

class MainTableViewController: UITableViewController, SearchTableDelegate {...}

并使用协议中的函数:

    func passSelectedValue(selected value: String) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if let destinationVC = storyboard.instantiateViewController(withIdentifier: "details") as? DetailsViewController{
        destinationVC.value = value
        self.navigationController?.pushViewController(destinationVC, animated: true)
    }
}

此外,在 MainController 中声明 SearchableViewController 时,不要忘记将 Searchable 的委托分配给自身:

searchableTableController.delegate = self