ios - 如何创建像下面这样的自定义导航栏?

标签 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

我正在尝试找出如何复制导航栏设计(如果它是自定义导航栏)?

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

如果导航栏是自定义的,我不确定为什么它没有出现在 segued View Controller 中,例如:

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
}

这会导致导航栏的高度保持静态,并且宽度不会填充 View 的宽度:

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)
}

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

无论做什么似乎都会填充 View 高度的 25%,我希望达到相同的结果。

有人知道我如何实现这一目标吗?

谢谢

更新:

我尝试使用 Collection View 的补充 View 加载 .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

最佳答案

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

首先创建标题单元格

class myCollectionViewHeaderView: UICollectionViewCell {
 ....
}

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

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

实现委托(delegate)方法:

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
}

关于ios - 如何创建像下面这样的自定义导航栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48134229/

相关文章:

iphone - 如何在 iphone 应用程序开发中的导航栏上的分段 Controller 上添加下一个和上一个按钮?

iphone - 如何使用 NSOutputStream 通过套接字发送 NSString

ios - ARKit 在赛道上小跳

ios - 由于编辑StyleForRowAt 而无法滑动

iOS 如何从底部滑入 View ,占导航栏+状态栏高度

objective-c - 如何移动屏幕上的导航栏位置

ios - 如何在从 UITableViewController 到 UIViewController 的 Unwind segue 中声明 UITableViewController

ios - 尝试在 iOS 上组装

swift - Swift 中的 IBOutlet 和 IBAction

objective-c - 比较 Swift 中的 AnyObject