我正在使用 VIPER 并尝试实现自定义 NavBarController

问题描述

我正在尝试创建一个自定义导航栏,并想在左侧添加一个标题,并在右侧添加一个聊天图标。

就是这样

NavBar UI Design

但它没有显示任何项目。背景颜色是唯一有效的自定义

我这样称呼它

let garageVC = HomeNavController(rootViewController: GarageRouter.assembleModule(),title: "My Garage")

我的导航类

import UIKit

class HomeNavController: UINavigationController {
    
    var tabTitle: String?
    
    init(rootViewController: UIViewController,title: String) {
        super.init(rootViewController: rootViewController)
        self.tabTitle = title
        configure()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configure()
    }
    
    private func configure() {
        
        navigationBar.isHidden = false
        navigationBar.isTranslucent = false

        navigationBar.tintColor = .white
        navigationBar.barTintColor = .primary
        
        let nameLabel = UILabel(frame: .zero)
        nameLabel.textColor = .white
        nameLabel.tintColor = .white
        nameLabel.text = tabTitle
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: nameLabel)

        
        let chatButton = UIButton(type: .system)
        chatButton.setimage(UIImage(named: "home-chat")?.withRenderingMode(.alwaysOriginal),for: .normal)
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: chatButton)
        chatButton.imageEdgeInsets = UIEdgeInsets(top: 0.0,left: 0,bottom: 0,right: -10)
        chatButton.addTarget(self,action: #selector(chatClicked),for: .touchUpInside)
        
    }
    
    @objc func chatClicked() {
        print("Chat clicked")
    }
}

输出

my output design

解决方法

您可以创建带有标签和按钮的自定义视图,并将其设置为 <com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto" android:id="@+id/adView" android:layout_width="match_parent" android:layout_height="wrap_content" ads:adSize="SMART_BANNER" ads:adUnitId="ca-app-pub-xxx/xxx"> </com.google.android.gms.ads.AdView> titleView 上的 navigationItem

Check out this answer

编辑:

或者您可以将新标签设置为 HomeNavController

How do I left align the title of a navigation bar in Xcode?

,

如果你想在另一个页面上实现这个导航,你可以只创建自定义视图控制器而不是创建自定义导航控制器。

import UIKit

class CustomViewController: UIViewController {
    
    var tabTitle: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }

    private func configure() {
    
        navigationController?.navigationBar.isHidden = false
        navigationController?.navigationBar.isTranslucent = false

        navigationController?.navigationBar.tintColor = .white
        navigationController?.navigationBar.barTintColor = .primary
    
        let nameLabel = UILabel(frame: .zero)
        nameLabel.textColor = .white
        nameLabel.tintColor = .white
        nameLabel.text = self.tabTitle
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: nameLabel)

    
        let chatButton = UIButton(type: .system)
        chatButton.setImage(UIImage(named: "home-chat")?.withRenderingMode(.alwaysOriginal),for: .normal)
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: chatButton)
        chatButton.imageEdgeInsets = UIEdgeInsets(top: 0.0,left: 0,bottom: 0,right: -10)
        chatButton.addTarget(self,action: #selector(chatClicked),for: .touchUpInside)
    
    }

    @objc func chatClicked() {
         print("Chat clicked")
    }
}

现在,如果您想更改具有相同导航栏的视图控制器,您可以使用 CustomViewController。

class HomeViewController: CustomViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

如果你想改变标题,你可以在呈现或添加到 rootviewcontroller 之前设置视图控制器的标题

let viewController = HomeViewController()
viewController.tabTitle = "Hommme"
let navController = CustomViewController(rootViewController: viewController)
self.present(navController!,animated: true,completion: nil)

如果您使用故事板,您可以在 attibure 检查器上更改视图控制器的标题。

注意:

  • 如果要在演示过程中更改标题,则需要调整代码。
  • 如果这个导航栏只显示在 1 个页面上,你只需要直接在视图控制器中更改而不是创建自定义视图控制器。
,

我对其进行了半硬编码。我已经在我的视图控制器上实现了 configure() 函数并且它可以工作。遗憾的是,我必须为 tabBar 上的每个视图控制器拖动此函数。