我已经将Xcode升级到11,并且在UINavigationBarDelegate协议中的shouldPop()方法下,在我们的iOS应用的iOS13模拟器/真实设备上发现了一些问题:

该协议有4种方法,其中3种运行良好,仅此shouldPop()不再起作用。
如果我在以前的iOS版本的设备/模拟器上运行该应用程序,则一切正常,应调用shouldPop(),但如果我在iOS13上运行该应用程序,则不调用houldPop()。
因为在以前的iOS版本上一切正常,所以调用了4种协议方法中的3种,并且我在文档中找不到不支持/不建议使用shouldPop()的问题,这似乎是一个错误,但是我不确定。

你们对此有什么想法吗?

谢谢,
提比

private class DummyNavigationController: UINavigationController, UINavigationControllerDelegate, UINavigationBarDelegate {
    var rootViewController: UIViewController? {
        didSet {
            self.delegate = self
        }
    }

    func navigationBar(_ navigationBar: UINavigationBar, didPush item: UINavigationItem) {
        // working
    }

    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
        // working
        return true
    }

    func navigationBar(_ navigationBar: UINavigationBar, didPop item: UINavigationItem) {
        // working
    }

    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        // not working
        return true
    }
}

private class DummyViewController: UIViewController {
    convenience init(_ showBackText: Bool) {
        self.init()
        if !showBackText {
            self.navigationItem.title = ""
        }
    }
}

class OpenModalWithNavigation {

    static func present(viewController: UIViewController,
                        parentViewController: UIViewController,
                        showBackText: Bool = false,
                        presentationStyle: UIModalPresentationStyle = .overCurrentContext,
                        transitionStyle: UIModalTransitionStyle = .crossDissolve) {

        let navController = DummyNavigationController()
        navController.rootViewController = parentViewController
        navController.pushViewController(DummyViewController(showBackText), animated: false)
        navController.pushViewController(viewController, animated: false)
        navController.modalPresentationStyle = presentationStyle
        navController.modalTransitionStyle = transitionStyle
        parentViewController.present(navController, animated: true, completion: nil)
    }
}


编辑:
经过对大代码的调查后,是的,我们从自定义的“后退”按钮调用popViewController()。这与下面的代码有点类似:如果我通过qqq实例的OpenModalWithNavigation.present()将DummyNavigationController放入,则不触发shouldPop()。

class qqq: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.green

        let button = UIButton(type: .custom)
        let backImage = UIImage(named: "back")
        button.setImage(backImage, for: .normal)
        button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
        button.addTarget(self, action: #selector(self.goBack), for: .touchUpInside)

        let backButton = UIBarButtonItem(customView: button)
        self.navigationItem.leftBarButtonItem = backButton
    }

    @objc func goBack() {
        self.navigationController?.popViewController(animated: true)
    }
}


另外,qqq的简化形式(请参见下文),将无法使用...似乎与popViewController()有关

class qqq: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: {
            self.navigationController?.popViewController(animated: true)
        })
    }
}


如果按默认的后退按钮,一切正常,应该调用shouldPop()。当我们调用popViewController()时没有发生-这仅在运行iOS13的设备/模拟器上发生;对于iOS13之前的版本:一切都很好。

最佳答案

从导航控制器类声明中删除私有访问修饰符。

class DummyNavigationController: UINavigationController, UINavigationControllerDelegate, UINavigationBarDelegate {
    var rootViewController: UIViewController? {
        didSet {
            self.delegate = self
        }
    }

    func navigationBar(_ navigationBar: UINavigationBar, didPush item: UINavigationItem) {
        // working
    }

    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
        // working
        return true
    }

    func navigationBar(_ navigationBar: UINavigationBar, didPop item: UINavigationItem) {
        // working
    }

    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        // working
        return true
    }
}


专用访问将实体/类的使用限制为封闭的声明以及同一文件中该声明的扩展。

如果您仍然遇到问题,请告诉我。

08-05 22:12