【问题标题】:Tab Navigation Bar Consistency选项卡导航栏一致性
【发布时间】:2017-05-09 15:10:45
【问题描述】:

我有一个带有不同标签的导航标签栏。我希望有一个功能,当我按下选项卡时,无论我身在何处,它都会将我带到视图中。

例如:

“手册”标签栏 “打开文档”另一个标签栏

通过点击“手册”然后点击打开文档导航到手册视图时;我希望看到打开的数据模块列表,而不是跳转到“最后一个打开的数据模块”。

我怎样才能做到这一点?

“打开文档”的代码如下:

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)
}

}

【问题讨论】:

  • 您能否提供屏幕截图或代码来说明您正在尝试做什么?我很难理解你的问题。
  • 我用代码更新了问题。此代码基本上在表格视图中显示手册,当单击单元格时,它将显示该特定单元格的详细页面。现在,当我切换选项卡栏然后返回此选项卡(打开文档)时,它会向我显示详细视图,但我希望我向我显示表格视图。希望它现在更有意义,你可以帮助我。如果有什么问题,问我会回复的。

标签: swift ipad uinavigationbar


【解决方案1】:

你可以设置你的UITabBarControllerDelegate,然后实现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
}

如果它仍然在视图中时弹出回您的 tableview,这可能是糟糕的用户体验。另一种选择是等到转换完成,然后在 viewController 消失后弹出它。

【讨论】:

  • 我怎样才能让它等到转换完成,然后在 viewController 消失后弹出它?
  • 如何设置 UITabBarControllerDelegate?请帮忙。赞赏。
  • 我已经这样设置了 UITabBarControllerDelegate:class DocumentListViewController: BaseViewController, UITabBarControllerDelegate {
  • 这是 func 实现: private func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: DocumentListViewController) -> Bool { if (tabBarController.selectedViewController?.navigationController?.shouldPerformSegue(withIdentifier: "DocumentViewController",发件人:自己))! { navigationController?.popViewController(animated: false) } return true } 编译但不执行功能。能否请你帮忙?提前致谢。
【解决方案2】:

已修复。我所要做的就是在我的 RootTabBarViewController 中设置 UITabBarController 并在 viewDidLoad() 中设置“delegate = self”并实现以下功能:

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 1 {

   if let vc = viewController as? UINavigationController {          
   vc.popViewController(animated: false)
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2020-11-05
    相关资源
    最近更新 更多