是否可以通过协议自定义 UINavigationBar?

Is it possible to customize UINavigationBar by protocol?

我想为某些视图控制器自定义 UINavigationBar。由于某些原因,我不能只是简单地扩展 UIViewController。所以我试图通过协议来做到这一点。

我尝试过的:

protocol TransparentNavigationBarProtocol {
    func makeNavigationBarTransparent()
}

extension TransparentNavigationBarProtocol where Self: UIViewController {

    func makeNavigationBarTransparent() {
        if let navController = navigationController {
            navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
            navController.navigationBar.shadowImage = UIImage()
            navController.navigationBar.tintColor = UIColor.white
            navController.navigationBar.barStyle = .blackTranslucent
            navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
            navController.navigationBar.backgroundColor = .clear
        }
    }

}

我添加了一些断点,显示函数已成功调用,但导航栏没有改变。所以我想知道是否可以通过协议实现这一点?

对于Xcode11,你需要设置一个图像,而不是nil

此外,在您的 viewcontroller 的 viewWillAppear 中,您需要调用 makeNavigationBarTransparent()

func makeNavigationBarTransparent() {
    if let navController = navigationController {
        navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
        navController.navigationBar.shadowImage = UIImage()
        navController.navigationBar.tintColor = UIColor.init(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)
        navController.navigationBar.barStyle = .default
        navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)]
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    makeNavigationBarTransparent()
}