如何创建类似以下应用的自定义导航栏?

时间:2018-01-07 04:06:34

标签: ios swift uinavigationbar

我正在开发一个类似于以下应用的应用: enter image description here

在绿色框中,我相信它只是一个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)

    }
}

这实现了以下目标:

enter image description here

我试图找出如何复制导航栏设计,如果它是一个自定义导航栏开始?

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

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

enter image description here

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

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
}

这导致导航栏的高度保持静止,宽度不会填满视图的宽度:

enter image description here

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%,我希望得到相同的结果。

有没有人有任何想法我能做到这一点?

由于

更新

我尝试使用集合视图的补充视图加载.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()
    }
}

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

enter image description here

1 个答案:

答案 0 :(得分:0)

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

首先创建标题单元格

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
}

希望有所帮助

有关更新

将它放在viewWillAppear:

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
}