首页 > 解决方案 > 更改从代码初始化的视图控制器时如何修复消失的标签栏控制器

问题描述

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

我使用表视图控制器作为显示搜索栏结果的视图。当我选择单元格(搜索结果)时,我正在更改显示结果的视图控制器。但这一个是从情节提要完成的。我知道从代码执行的表视图控制器不会通过导航栏从以前的控制器“继承”标签栏。但这应该从代码中执行。

初始化搜索结果控制器
 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


 }
此代码仅负责将值传递给选定的视图控制器。
 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(显示结果并切换到detail controller的Table View Controller)。

故事板 预期的 失败的 将标签栏设置为根控制器或其他东西的最佳方法是什么。如果控制器是从情节提要或代码初始化的,我只需要标签栏在所有视图控制器中都没有关系。

我整天都在努力解决这个问题,但我不知道怎么做......我感谢每一个帮助!

谢谢!

标签: iosswiftxcodeuitabbarcontrolleruistoryboard

解决方案


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

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

现在它按预期工作。

简单的代码如下所示:

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

在 Searchable View Controller 中声明:

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 分配给 self:

searchableTableController.delegate = self

推荐阅读