Reputation: 201
I have a navigation tab bar with different few tabs. I would want to have a functionality that when I press on a tab it would always bring me to the view regardless of where I am.
For example:
"Manuals" a tab bar "Open Documents" another tab bar
When navigating to the manuals view by hitting "Manuals" and then hitting open document; I would want to expected to see the list of open data modules instead I jump to the "last open data module".
How can I achieve this?
The code for "Open Documents" is below:
class DocumentListViewController: BaseViewController {
// MARK: - IB Outlets
@IBOutlet weak var tableView: UITableView!
// MARK: - Properties
var webview:WKWebView!
var documentsToDelete:[Node]?
// MARK: - VC Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
title = NSLocalizedString("Open Documents", comment: "")
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: "TablistHeader", bundle: Bundle.main), forHeaderFooterViewReuseIdentifier: "Header")
webview = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
webview.navigationDelegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//MARK: - Business Logic
func remove(documents nodes:[Node]) {
documentsToDelete = nodes
if let section = nodes.first?.sections.first, let urlString = section["url"], let nodePath = nodes.first?.path {
var readAccessFolder:URL?
let pathComponents = URL(fileURLWithPath: nodePath).pathComponents
if pathComponents.count >= 2 {
let rootFolder = "\(pathComponents[1])"
readAccessFolder = URL(fileURLWithPath: "\(PackageManager.shared.packageFolder)\(rootFolder)")
}
let url = URL(fileURLWithPath: urlString)
_ = webview.loadFileURL(url, allowingReadAccessTo: readAccessFolder!)
}
else {
deleteDocumentsFromList()
}
}
fileprivate func deleteDocumentsFromList() {
if let indexes = self.documentsToDelete?.flatMap({ (node) -> Int? in
return PackageManager.shared.openNodes.index(of: node)
})
{
for i in indexes.reversed() {
PackageManager.shared.openNodes.remove(at: i)
}
self.tableView.reloadData()
webview.load(URLRequest(url: URL(string:"about:blank")!))
}
}
func resetProcedureStepCheckboxes() {
if let dmcs = documentsToDelete?.flatMap({ (node) -> String? in
return node.moduleCode
})
{
webview.evaluateJavaScript("resetProcedureStepCheckboxes(\(dmcs))") { (result, error) in
print(error as Any)
self.deleteDocumentsFromList()
}
}
}
override func showDocumentViewController(for node:Node?, openSegment segment:Int = 0) {
let contentView = self.storyboard?.instantiateViewController(withIdentifier: "DocumentViewController") as! DocumentViewController
contentView.currentNode = node
contentView.initalSegment = segment
contentView.navigationItem.titleView = UILabel.forTitleView(withText: node?.title)
navigationController?.pushViewController(contentView, animated: true)
}
}
// MARK: - UITableViewDataSource
extension DocumentListViewController : UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
if PackageManager.shared.openNodes.count > 0 {
tableView.removeEmptyMessage()
return 1
} else {
tableView.showEmptyMessage(message: NSLocalizedString("No open documents", comment: ""), viewController: self)
return 0
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return PackageManager.shared.openNodes.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let node = PackageManager.shared.openNodes[indexPath.row]
var dText = ""
if let man = node.manual {
dText = "\(man)\n"
}
if let mc = node.moduleCode {
dText = "\(dText)" + "\(mc)"
}
let cell = tableView.dequeueReusableCell(withIdentifier: "OpenDocumentCell", for: indexPath)
cell.imageView?.image = node.image()
cell.imageView?.contentMode = .scaleAspectFill
cell.editingAccessoryType = .none
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = node.title
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.text = dText
return cell
}
}
// MARK: - UITableViewDelegate
extension DocumentListViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let node = PackageManager.shared.openNodes[indexPath.row]
showDocumentViewController(for: node)
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if PackageManager.shared.openNodes.count == 0 {
return 0
}
return 50
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if PackageManager.shared.openNodes.count == 0 {
return nil
}
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header") as! TablistHeader
header.titleLabel.text = String.localizedStringWithFormat(NSLocalizedString("%i open documents", comment: ""), PackageManager.shared.openNodes.count)
header.onDelete = { [weak self] in
guard let strongSelf = self else { return }
// show action sheet
let title = NSLocalizedString("Clear list", comment: "")
let msg = NSLocalizedString("Do you really want to clear the list of open documents?", comment: "")
let options = UIAlertController(title:title, message: msg, preferredStyle: .alert)
let deleteAll = UIAlertAction(title: NSLocalizedString("Clear list", comment: ""),
style:.destructive,
handler: { (action) -> Void in
strongSelf.remove(documents: PackageManager.shared.openNodes)
})
options.addAction(deleteAll)
let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""),
style:.cancel,
handler: nil)
options.addAction(cancel)
strongSelf.present(options, animated: true, completion: nil)
}
return header
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let del = UITableViewRowAction(style: .destructive, title: NSLocalizedString("Delete", comment: ""), handler: { [weak self] (action, indexPath) -> Void in
guard let strongSelf = self else { return }
let node = PackageManager.shared.openNodes[indexPath.row]
strongSelf.remove(documents: [node])
})
return [del]
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
}
// MARK: - WKNavigationDelegate
extension DocumentListViewController : WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
resetProcedureStepCheckboxes()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(error)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let abs = navigationAction.request.url?.absoluteString, abs == "about:blank" {
decisionHandler(.cancel)
}
decisionHandler(.allow)
}
}
Upvotes: 0
Views: 85
Reputation: 201
Fixed. All I had to do was to set UITabBarController in my RootTabBarViewController and set "delegate = self" in viewDidLoad() and implement the below function:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 1 {
if let vc = viewController as? UINavigationController {
vc.popViewController(animated: false)
}
}
Upvotes: 1
Reputation: 2906
You could set your UITabBarControllerDelegate
and then implement shouldSelectViewController
:
func tabBarController(_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController) -> Bool {
// check if tabBarController.selectedViewController is navController
// containing your detailViewController. If so:
navController.popViewController(animated: false)
return true
}
This may be poor UX if it pops back to your tableview while it's still in view. Another option would be to wait until the transition is complete and then pop the viewController after it's out of view.
Upvotes: 1