如何创建像以下应用程序一样的自定义导航栏?

How to create a customized navigation bar like the following app?

我正在开发一个类似于以下应用程序的应用程序:

在绿框中,我相信它只是一个 UICollectionView,每行 2 UICollectionViewCells,我写了一些示例代码,如下所示:

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
{
    var imageName = [UIImage(named: "1"), UIImage(named: "2"), UIImage(named: "3"),
                     UIImage(named: "4"), UIImage(named: "5"), UIImage(named: "6"),
                     UIImage(named: "7"), UIImage(named: "1"), UIImage(named: "2"),
                     UIImage(named: "3"), UIImage(named: "4")]
    var nameArray = ["name 1", "name 2", "name 3",
                     "name 4", "name 5", "name 6",
                     "name 1", "name 2", "name 3",
                     "name 4"]

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

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return nameArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
       let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
        cell.imgImage.image = imageName[indexPath.row]
        cell.lblName.text! = nameArray[indexPath.row]
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    {
        let width = collectionView.frame.width / 2 - 1

        return CGSize(width: width, height: 80.0)
    }

    func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath)
    {
        let cell = collectionView.cellForItem(at: indexPath)
        cell?.backgroundColor = UIColor.lightGray
    }

    func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath)
    {
        let cell = collectionView.cellForItem(at: indexPath)
        cell?.backgroundColor = UIColor.yellow
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
    {
        return 1.0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
    {
        return 1.0
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {
        let MainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let desCV = MainStoryboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
        desCV.getImage = imageName[indexPath.row]!
        desCV.getName = nameArray[indexPath.row]
        self.navigationController?.pushViewController(desCV, animated: true)

    }
}

这实现了以下目标:

我想知道如何复制导航栏设计,如果它是自定义导航栏开始?

右上角有一个设置和天气按钮,所以我不相信它是一个导航栏,但我再次不确定。

如果导航栏是自定义的,我不确定为什么它没有出现在 segued 视图控制器中,例如:

到目前为止我尝试做的事情:

1.

override func viewDidLoad()
{
    super.viewDidLoad()

    let helperView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    helperView.backgroundColor = UIColor.red
    navigationItem.titleView = helperView
}

这导致导航栏的高度保持静态并且宽度不填满视图的宽度:

2.

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

    let height: CGFloat = 300 //whatever height you want
    let bounds = self.navigationController!.navigationBar.bounds
    self.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height + height)
}

导航栏高度再次保持默认高度。

所做的一切似乎填充了视图高度的 25%,我想达到相同的结果。

有人知道我该如何实现吗?

谢谢

更新:

我尝试使用 collection 视图的补充视图加载 .xib 如下:

class CustomHeader: UICollectionViewCell
{
    @IBOutlet var customHeaderImageView: UIImageView!
}

override func viewDidLoad()
{
    super.viewDidLoad()

    let headerNib = UINib(nibName: "CustomHeader", bundle: nil)
    sampleCollectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "CustomHeaderCell")
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    let size = CGSize(width: 375, height: 100)

    return size
}

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
{
    switch kind
    {
        case UICollectionElementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CustomHeaderCell", for: indexPath)
            return headerView

        default://I only needed a header so if not header I return an empty view
            return UICollectionReusableView()
    }
}

然而,结果不符合我的要求,因为 header 被添加到导航栏下方而不是取代它的位置:

在你的第一张照片中,我认为它不是自定义导航栏,而是 collectionView 补充视图(在本例中为 header):https://developer.apple.com/documentation/uikit/uicollectionviewdatasource/1618037-collectionview.

首先创建您的 header 单元格

class myCollectionViewHeaderView: UICollectionViewCell {
 ....
}

然后在您的 collectionView 中注册单元格:

myCollectionView.register(myCollectionViewHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: myCollectionViewHeaderViewCellId)

实现委托方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: SCREENW, height: headerHeight)
}

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: myCollectionViewHeaderViewCellId, for: indexPath)
    return headerView
}

希望对您有所帮助

待更新

把它放在你的视图中WillAppear:

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

        self.navigationController?.setNavigationBarHidden(true, animated: true)

// Put the following lines if you want to keep the slide to pop even if the navigation bar is hidden    
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self as? UIGestureRecognizerDelegate
}