Reputation: 284
I'm struggling with the problem which is when I'm switching view controllers connected with push segue then everything works as expected. The problem is that I have a search bar that executes Table View Controller from code and when I select the cell from that Table View Controller the next view controller is without tab bar.
I am using Table View Controller as a view that displays results from search bar. When I am selecting cell (result from searching) then I am changing view controller showing the results. But this one is done from storyboard. I know that the Table View Controller executed from code does not "inherits" tab bar from previous controllers through the navigation bar. But this one should be executed from code.
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
}
}
}
}
Also In Detail View Controller I had to create navigation bar programmatically in case if the segue was from the Search Result Controller.
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)
}
Bellow is screenshot of storyboard connection. This storyboard without navigation bar is of course this SearchResultController
(Table View Controller that displays results and switches to the detail controller).
What is the best way to set tab bar as a root controller or something. I just need the tab bar to be in all view controller doesn't matter if the controllers are initialize from storyboard or code.
I am trying all day to fix this but I don't know how.. I appreciate every help!
Thanks!
Upvotes: 1
Views: 1328
Reputation: 284
Ok, the problem was with segues. I tried to pass the value from another Controller, that has nothing in common with previous one so that was obvious that navigation bar and tab bar wasn't there. While dealing with separate serchable view controller, there should be added delegation, to pass the vale back to Main Controller. When interacting with searchable view controller, the procedure to pass the value to another view controller in my case looks like this:
Now it works like it supposed to.
The simple code looks like this:
protocol SearchTableDelegate {
func passSelectedValue(selected stock: String)
}
In Searchable View Controller declare:
var delegate: SearchTableDelegate!
In DidSelectedRowAt:
delegate.passSelectedValue(selected: selectedValue)
Now in Main Controller:
class MainTableViewController: UITableViewController, SearchTableDelegate {...}
And use the function from protocol:
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)
}
}
Also when declaring the SearchableViewController in MainController don't forget to assign delegate from Searchable to self:
searchableTableController.delegate = self
Upvotes: 1