ios - 更改从代码初始化的视图控制器时如何修复消失的标签栏控制器
问题描述
我正在努力解决这个问题,即当我切换与 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)。
将标签栏设置为根控制器或其他东西的最佳方法是什么。如果控制器是从情节提要或代码初始化的,我只需要标签栏在所有视图控制器中都没有关系。
我整天都在努力解决这个问题,但我不知道怎么做......我感谢每一个帮助!
谢谢!
解决方案
好的,问题出在segues上。我试图从另一个控制器传递值,它与前一个控制器没有任何共同之处,因此很明显导航栏和标签栏不存在。在处理单独的可搜索视图控制器时,应该添加委托,以将值传递回主控制器。在与可搜索视图控制器交互时,在我的例子中,将值传递给另一个视图控制器的过程如下所示:
- 当我开始在我的主控制器上输入新的可搜索视图控制器时
- 当我找到我需要的项目时,我通过 didSelectedRowAt 选择它
- 我通过委托函数传递选定的值
- 将委托添加到主控制器,应该从哪里完成 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
推荐阅读
- powershell - 将经典 SharePoint 页面转换为新式时出错 - 索引超出范围
- python - 如何动态使用不影响整个环境的产量
- typo3 - 如何使用翻译服务器更新 TYPO3 默认语言?
- hyperledger-fabric - Hyperledger Fabric:从使用 Node SDK 编写的链代码中调用 Python 脚本
- javascript - 为什么拖动事件上的 ctrlKey 属性没有立即更新?
- r - 在R中绘制不同颜色的累积直方图
- php - 计算两个日期之间的夜间时间
- node.js - 如何在 node.js lambda 中使用请求模块
- java - camunda 中 activitieventlistener 的替代方法是什么?
- java - 为什么我的 Swing GUI 没有显示所有添加的按钮?