如果没有在func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell中放置断点并逐步调试它,就无法在运行时显示我的自定义UICollectionViewCell。之后,我的自定义单元格将显示正常。 Xcode Builder或我的代码出了什么问题?

p / s:我通过className注册我的自定义UICollectionViewCell,如下所示:clvDishes.registerClass(PosItemsCollectionViewCell.classForCoder(), forCellWithReuseIdentifier: "DishesCollectionViewCell")并在代码中创建单元格的布局(不使用xib文件)

这是我的代码

class PosCollectionViewSource<T>: NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    var items:[T] = []
    var identifier:String!
    override init() {
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

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

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(identifier + "CollectionViewCell", forIndexPath: indexPath)

        switch(String(T)){
        case "PosItemsInfo":
            let itemsCell = cell  as! PosItemsCollectionViewCell
            let posItems = items as Any as! [PosItemsInfo]
            itemsCell.updateCell(posItems[indexPath.item])
            return itemsCell

        default : break
        }

        return cell
    }
}




class PosItemsCollectionViewCell: UICollectionViewCell{

        private var _lblItemName:UILabel!
        private var _lblItemPrice:UILabel!
        private var _vOverlayInfo:UIView!
        private var _imvPictureContainer:UIImageView!
        private var _vSeparate:UIView!
        private var _imvWarning:UIImageView!
        private var _imvSeason:UIImageView!
        private var _lblRemaining:UILabel!


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

            let uiFont = UIFont(name: "HelveticaNeue-Thin", size: 17) as UIFont?

            _lblItemName = UILabel()
            _lblItemName.textColor = UIColor.whiteColor()
            _lblItemName.font = uiFont

            _lblItemPrice = UILabel()
            _lblItemPrice.textColor = UIColor.whiteColor()
            _lblItemPrice.font = uiFont

            _vSeparate = UIView()
            _vSeparate.backgroundColor = UIColor(hexString: "FFFFFF", a: 0.5)

            _vOverlayInfo = UIView()
            _vOverlayInfo.backgroundColor = UIColor(hexString: "#000000", a:0.21)

            _imvPictureContainer = UIImageView()
            _imvPictureContainer.image = UIImage(named: "pos_DefaultDishIcon")

            _vOverlayInfo.addSubview(_lblItemName)
            _vOverlayInfo.addSubview(_lblItemPrice)
            _vOverlayInfo.addSubview(_vSeparate)

            _lblRemaining = UILabel()
            _lblRemaining.textColor = UIColor(hexString: "E86E2B")
            _lblRemaining.SetBorder("E86E2B", radius: 0)
            _lblRemaining.backgroundColor = UIColor.whiteColor()
            _lblRemaining.font = UIFont(name: "HelveticaNeue-Medium", size: 20)
            _lblRemaining.textAlignment = NSTextAlignment.Center

            _imvSeason = UIImageView()
            _imvSeason.image = UIImage(named: "pos_SeasonIcon")

            _imvWarning = UIImageView()


            contentView.addSubview(_imvPictureContainer)
            contentView.addSubview(_vOverlayInfo)
            contentView.backgroundColor = UIColor.whiteColor()
        }

        func updateCell(item:PosItemsInfo){
            _lblItemName.text = item.itemName
            _lblItemPrice.text =  item.itemPrice?.toString("%.2f")
            _lblRemaining.text = item.itemQtyRemaining?.toString()

            if item.itemQtyStatus == PosItemQtyStatus.SoldOut{
                contentView.addSubview(_imvWarning)
                _imvWarning.image = UIImage(named: "pos_SoldOut")
            }
            else if item.itemQtyStatus == PosItemQtyStatus.LowInStock{
                contentView.addSubview(_imvWarning)
                contentView.addSubview(_lblRemaining)
                _imvWarning.image = UIImage(named: "pos_LowStock")
                _lblRemaining.text = item.itemQtyRemaining?.toString()
            }

            if item.itemIsSeason == true {
                contentView.addSubview(_imvSeason)
            }


        }

        override func layoutSubviews() {
            _vOverlayInfo.frame = CGRect(x: 0, y: contentView.frame.height - 60, width: 205, height: 60)
            _imvPictureContainer.frame = CGRect(x: 0, y: 0, width: 205, height: 160)
            _lblItemName.frame = CGRect(x: 10, y: 0, width: contentView.frame.width - 20, height: _vOverlayInfo.frame.height/2 )
            _lblItemPrice.frame = CGRect(x: 10, y: _lblItemName.frame.height, width: contentView.frame.width - 20, height: _vOverlayInfo.frame.height/2 )
            _vSeparate.frame = CGRect(x: 8, y: _lblItemName.frame.height, width: contentView.frame.width - 16, height: 1 )
            _lblRemaining.frame = CGRect(x: (contentView.frame.width - 50)/2, y: 40, width: 50, height: 50)
            _imvWarning.frame = CGRect(x: 125, y: 0, width: 81, height: 74)
        }

        override func didMoveToSuperview() {
            self.setNeedsLayout()
            self.layoutIfNeeded()
        }

        required init?(coder aDecoder: NSCoder) {
            super.init(coder:aDecoder)
        }




    class PosDishesVCtrl: PosBaseController {

    @IBOutlet weak var clvDishes: UICollectionView!

    private var _clvDataSource:PosCollectionViewSource<PosItemsInfo>!
    private var _items:[PosItemsInfo]!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: String(self.dynamicType), bundle: nil)
    }

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

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


    func modifiedOrUpdateUI(){
        clvDishes.setCollectionViewLayout(LayoutGridType, animated: false)
        clvDishes.registerClass(PosItemsCollectionViewCell.classForCoder(), forCellWithReuseIdentifier: "DishesCollectionViewCell")
        clvDishes.backgroundColor = UIColor(hexString: "979797", a: 1)
        clvDishes.showsHorizontalScrollIndicator = false
        clvDishes.showsVerticalScrollIndicator = false
        clvDishes.pagingEnabled = false
        clvDishes.autoresizingMask = UIViewAutoresizing.FlexibleWidth
        clvDishes.contentSize = CGSize(width: clvDishes.frame.width, height: clvDishes.frame.height)
        clvDishes.scrollsToTop = false
    }

    func renderDishes(){
        if(_clvDataSource == nil){
            _clvDataSource = PosCollectionViewSource<PosItemsInfo>()
            _clvDataSource.identifier = "Dishes"
            _items = [PosItemsInfo]()
        }

        for var i = 0; i < 12; i++ {
            let item = PosItemsInfo()
            item.itemName = "Dish " + String(i)
            item.itemPrice = Double(i)
            item.itemQtyRemaining = 4
            if(i%2 == 0){
                item.itemIsSeason = true
                item.itemQtyStatus = PosItemQtyStatus.LowInStock
            }
            else {
                item.itemQtyStatus = PosItemQtyStatus.SoldOut
            }
            _items.append(item)
        }

        clvDishes.setCollectionViewLayout(LayoutGridType, animated: false)
        _clvDataSource.items = _items
        clvDishes.dataSource = _clvDataSource

        clvDishes.delegate = PosCollectionViewDelegate(ctr: self)
        clvDishes.reloadData()
        clvDishes.collectionViewLayout.invalidateLayout()
    }

}


任何想法将不胜感激!

最佳答案

看起来像您的DataSource方法:

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


总是返回零。您的行索引对应于您将在此处返回的项目(单元格)数。

编辑:

查看您提供的代码,显然您没有将任何项目添加到PosCollectionViewSource.items数组,因此我希望items.count返回零。如果没有,那么您必须将项目添加到数组中的其他位置(在尚未发布的源代码中)。

查看您的代码,我注意到您设置自定义单元格类并使用它的方式有些复杂(可能是错误的),并且可能会更好。

假设您要在items数组中的某个位置添加元素,让我们尝试另一种方法:

这是我用于具有reuseIdentifier s(UITableViewCellUICollectionViewCell等)的单元格类型的模式:

class CustomCell: UICollectionViewCell {
    // This will do the right thing for CustomCell and its subclasses
    class var reuseIdentifier: String { return "\(self)" }
}


现在,当您注册自定义类时,请执行以下操作:

collectionView.registerClass(CustomCell.self, CustomCell.reuseIdentifier)


并像这样获取一个:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CustomCell.reuseIdentifier, forIndexPath: indexPath)
        as! CustomCell

    // setup the cell as necessary:
    cell.contentView.backgroundColor = UIColor.yellowColor()

    return cell
}

关于ios - UICollectionViewCell仅在逐步调试时显示,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34690636/

10-12 04:32