如果没有在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(UITableViewCell
,UICollectionViewCell
等)的单元格类型的模式: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/