我有两个不同的单元格类型类,我正试图用PayNowCell类创建第一个indexpath,让它保持显示。而其他单元格是类签出单元格。现在问题出在我的func numberofitems部分。当前我正在使用return checkout.count,但在加载视图时它缺少PayNowCell。如果我让它返回checkout.count+1以使PayNowCell始终可用;我的程序将崩溃,错误索引超出范围。数组签出是一个全局变量。有人能解释原因并提供修复吗?被困在这上面有一段时间了。代码如下。

class CheckoutController: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout  {

    var inventoryTabController: InventoryTabController?

    override init(frame: CGRect){
        super.init(frame: frame)
        setupViews()

        NotificationCenter.default.addObserver(forName: .arrayValueChanged, object: nil, queue: OperationQueue.main) { [weak self] (notif) in
            self?.collectionView.reloadData()
        }

    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func loadItems() -> [Item]? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: Item.ArchiveURL.path) as? [Item]
    }

    func saveItems() {
        let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(checkout, toFile: Item.ArchiveURL.path)
        if !isSuccessfulSave {
            print("Failed to save items...")
        }
    }

    func addItem(item: Item) {
        items.append(item)
        collectionView.reloadData()
    }

    func editItem(item: Item, index: Int) {
        items[index] = item
        collectionView.reloadData()
    }

    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Identify which segue is occuring.
        if segue.identifier == "ShowDetail" {
            let itemDetailViewController = segue.destination as! AddItemController

            // Get the cell that generated this segue.
            if let selectedItemCell = sender as? InventoryCell {
                let indexPath = collectionView.indexPath(for: selectedItemCell)!
                let selectedItem = items[indexPath.row]
                itemDetailViewController.item = selectedItem
            }
        }
        else if segue.identifier == "AddItem" {
            print("Adding new meal.")
        }
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        cv.dataSource = self
        cv.delegate = self

        cv.backgroundColor = UIColor.rgb(r: 247, g: 247, b: 247)
        return cv
    }()

    let cellId = "cellId"
    let paynow = "paynow"
    func setupViews() {
        backgroundColor = .brown

        addSubview(collectionView)

        addConstraintsWithFormat("H:|[v0]|", views: collectionView)
        addConstraintsWithFormat("V:|[v0]|", views: collectionView)
        collectionView.indicatorStyle = UIScrollViewIndicatorStyle.white

        collectionView.register(PayNowCell.self, forCellWithReuseIdentifier: paynow)

        collectionView.register(CheckoutCell.self, forCellWithReuseIdentifier: cellId)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return checkout.count //init number of cells
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if indexPath.item == 0 {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "paynow", for: indexPath) as! PayNowCell //init cells
        return cell
        }else{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CheckoutCell //init cells
        print("Printing this \(checkout.count)")
        cell.item = checkout[indexPath.item]
        return cell
        }

    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        //let item = items[indexPath.item]
        //inventoryController?.showItemDetailForItem(item: item, index: indexPath.item)
        print("selected")
        print(indexPath.item)
        collectionView.reloadData()
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if indexPath.item == 0 {
            return CGSize(width:frame.width, height: 100) //each cell dimensions
        }else{
            return CGSize(width:frame.width, height: 150) //each cell dimensions
        }
    }

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

最佳答案

最好将集合视图重新排列为两个部分:
第0节:PayNow单元格(仅1个单元格)
第1节:签出单元格(使用签出数组列表)
那么您就不会对indexPath.item问题有任何混淆了。

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return section == 0 ? 1 : checkout.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    if indexPath.section == 0 {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "paynow", for: indexPath) as! PayNowCell //init cells
        return cell
    } else {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CheckoutCell //init cells
        print("Printing this \(checkout.count)")
        cell.item = checkout[indexPath.item]
        return cell
    }

}

关于ios - UICollection NumberOfItemsInSections问题向常量添加常量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41421205/

10-14 16:54
查看更多