如何在Swift Xcode中创建自定义导航栏?

6

我正在为我的iOS毕业项目开发一款聊天应用。我设计了以下导航栏:

enter image description here

现在我正在尝试在我的Xcode项目中开发上面的图形,但我不知道这是否是实现它并获得像图形一样的效果的正确方法。
我使用一个xib文件,在我的ViewController.swift中使用它的实例进行加载。然后将其作为navigationItem的titleView添加:
let helperView = HelperView()
navigationItem.titleView = helperView

这是以上代码片段的结果:

enter image description here

这个结果的问题是它重叠了左侧的按钮项,还有一个问题,我还没有解决,那就是当消息气泡有多行时(最多3行),它能够具有动态高度。

enter image description here

有人在Xcode中使用这种设计有经验吗?这是正确的方法吗?还是有更好的实现方法?也许可以使用自定义UINavigationController类?

2个回答

5
尝试创建您想要的整个导航视图,这意味着宽度等于视图的宽度,然后尝试使用此代码将其添加。
    navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    navigationController?.navigationBar.shadowImage = UIImage()
    navigationController?.navigationBar.backgroundColor = .clear

    navigationController?.view.insertSubview(subview, belowSubview: navigationController?.navigationBar)

这将使您的导航栏变得不可见,但仍显示导航栏按钮。
更新,由dimpiax提供。
但是最好覆盖您的UINavigationController类,并在viewDidLoad中设置视图。
navigationBar.shadowImage = UIImage()
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.backgroundColor = .clear

在依赖的视图控制器中展示特定视图。

所以如果我理解正确的话,我应该在Xib文件中正确创建头像和消息气泡,然后将上述代码添加到viewDidAppear函数中?subview应该是什么? - Caspert
子视图是您要添加的视图,在这种情况下是您的 helperView。您可以将上述代码添加到 viewDidLoad 中,但请保留指向您的 helperView 的指针变量,以便在 viewDidLayoutSubview 中调整框架大小。 - Tj3n
好的,你最后说的指针变量部分是什么意思?你是说它的框架应该可以根据内容进行调整大小吗? - Caspert
我的意思是,如果你把这段代码放在 viewDidAppear 中,它可能会出现闪烁的情况;如果放在 viewDidLoad 中,它可能会有错误的框架。因此,你可能想要在视图控制器范围内声明 headerView,以便在 viewDidLayoutSubview 中更改其框架。 - Tj3n
那么在viewdidLayoutSubview函数中添加上述代码是最好的方式吗?如果我理解错了,请原谅。 - Caspert
将其添加到 viewDidLoad 中,但在 viewDidLayoutSubviews 中更改 headerView 的 frame。 - Tj3n

0
// --------------------------------------------------------
// MARK:- Navigation SetUp
// --------------------------------------------------------

private func _navigationBarSetUp(){
    
    ///# Navigatoin bar and title #///
    
    navigationController?.navigationBar.isHidden = false
    navigationItem.title = vEditScreenName
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : ColorTheme.white, NSAttributedString.Key.font: UIFont(descriptor: UIFontDescriptor(name: "Poppins-Regular", size: 20), size: 20)]
    self.view.backgroundColor = ColorTheme.vidBoomBrandPurple
    
    ///# Navigation bar back button #///
    
    let btnBack = UIButton(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
    btnBack.setImage(UIImage(named: "icon_back_arrow"), for: .normal)
    btnBack.addTarget(self, action: #selector(_handlebtnBackTapped), for: .touchUpInside)
    navigationItem.leftBarButtonItem = UIBarButtonItem(customView: btnBack)
    
    ///# Navigation bar explore button #///
    
    let btnExport = UIButton(frame: CGRect(x: 0, y: 0, width: 80, height: 25))
    btnExport.setTitle("Export", for: .normal)
    btnExport.backgroundColor = .orange
    btnExport.layer.cornerRadius = 18
    btnExport.addTarget(self, action: #selector(_handleBtnExportTapped), for: .touchUpInside)
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: btnExport)
}


// --------------------------------------------------------
// MARK:- UIBarButtonItem Action
// --------------------------------------------------------

@objc fileprivate func _handlebtnBackTapped() {
    self.player.stop()
    navigationController?.popViewController(animated: true)
    navigationController?.navigationBar.isHidden = true
}

@objc func _handleBtnExportTapped(){
    self.player.stop()
    let svc = ShareVideoVC(nibName: "ShareVideoVC", bundle: nil)
    svc.videoString = videoString
    saveFile()
    self.navigationController?.pushViewController(svc, animated: true)
}

你能否添加一些关于如何使用这段代码的细节?这些方法应该放在哪里,我们需要从特定的位置/地点手动调用它们吗? - Cristik
将此代码添加到ViewController类中,但不要放在viewdidload中,并在viewdidload中调用该函数。 - Zeel Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接