【问题标题】:UICollectionView cell views overlappingUICollectionView 单元格视图重叠
【发布时间】:2015-03-11 19:33:36
【问题描述】:

我的单元格像这样重叠:

我的cellForItemAtIndexPath 是这样的:

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

cell.backgroundColor = UIColor(red: 27.0/255.0, green: 38.0/255.0, blue: 52.0/255.0, alpha: 1.0)
let textFrame = CGRect(x: 0, y: cell.frame.height * 0.30, width: cell.frame.width, height: cell.frame.height)
var textLabel: UILabel! = UILabel(frame: textFrame)
textLabel.font = UIFont(name:"Helvetica-Light", size: 14.0)
textLabel.textAlignment = .Center
textLabel.textColor = UIColor.whiteColor()

println(categoryArray[indexPath.row].category)

textLabel.text = categoryArray[indexPath.row].category
var cellImage = UIImage(named: categoryArray[indexPath.row].catImage)//Array(Array(model.categories.values)[cellCount])[1]

let imageSize = cell.frame.height * 0.45

let imageView = UIImageView(image: cellImage as UIImage?)
imageView.frame = CGRect(x: (cell.frame.width / 2) - (imageSize / 2), y:cell.frame.height * 0.15, width: imageSize, height: imageSize)

var bottomBorder: UIView = UIView(frame:CGRectMake(0, cell.frame.height - 1.0, cell.frame.width, 5));
//bottomBorder.backgroundColor = UIColor(rgba: Array(Array(model.categories.values)[cellCount])[0] as String)
bottomBorder.backgroundColor = UIColor(rgba: "#A64259")

cell.addSubview(imageView)
cell.addSubview(bottomBorder)
cell.addSubview(textLabel)

cellCount++
return cell
}

我知道它会重复使用单元格,好主意...除了如何防止单元格文本重叠?


编辑 - 潜在解决方案 #1

由于这些子视图不断被修改,我想,如果我只是将它们转储并创建新的,然后我使用:

for view in cell.subviews {
  view.removeFromSuperview()
}

这似乎起到了作用。我怀疑这比仅仅修改子视图中特定元素的值有更多的开销。将进一步调查。

【问题讨论】:

    标签: swift ios8 uicollectionview


    【解决方案1】:

    发生这种情况的原因是单元格被重复使用,并且您最终将图像作为子视图多次添加到同一个 UICollectionViewCell 对象。您可以创建一个扩展 UICollectionViewCell 的自定义类,以便您可以保留添加的 imageView。

    class ImageCell : UICollectionViewCell {
        private(set) var imageView : UIImageView?
        private(set) var textLabel : UILabel?
    
        func setImage(image: UIImage?) {
            if self.imageView == nil {
                let imageSize = cell.frame.height * 0.45
                self.imageView = UIImageView()
                self.imageView.frame = CGRect(x: (self.frame.width / 2) - (imageSize / 2), y:self.frame.height * 0.15, width: imageSize, height: imageSize)
                self.addSubview(imageView!)
            }
    
            imageView!.image = image
        }
    
        func setLabel(text: String) {
            if self.textLabel == nil {
                let textFrame = CGRect(x: 0, y: self.frame.height * 0.30, width: self.frame.width, height: self.frame.height)
                self.textLabel = UILabel(frame: textFrame)
                textLabel.font = UIFont(name:"Helvetica-Light", size: 14.0)
                textLabel.textAlignment = .Center
                textLabel.textColor = UIColor.whiteColor()
            }
    
            textLabel.text = text
        }
    }
    

    然后在你的 cellForItemAtIndexPath 中:

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as ImageCell
    
    var cellImage =  UIImage(named: categoryArray[indexPath.row].catImage)
    cell.setImage(cellImage)
    cell.setLabel(categoryArray[indexPath.row].category)
    

    显然,您必须对其进行自定义以获得相同的布局,但这应该可以帮助您入门。

    【讨论】:

      【解决方案2】:

      好吧,因为它重用了单元格,并且由于您在每次调用时都向单元格添加子视图,所以您最终会在同一个单元格中看到多个重叠的视图!

      相反,您可能只想添加一次子视图,标记它们,然后在被调用以提供一个单元格出队,使用它们的标签检索子视图,并根据需要设置它们的属性。

      【讨论】:

      • 由于我是 swift 和 ios 的新手,所以很多这些事情我都不确定该怎么做。我现在正在尝试。
      • 如果你理解了问题应该很容易。您基本上是在重用少量单元格,然后在每次调用 cellForItemAtIndexPath 时向它们添加视图。因此,您只需设置已添加的视图的属性,而不是添加视图。如果您需要进一步的帮助,请告诉我。
      • 从概念上讲,我理解这个问题。执行此操作的实际代码是我不确定的地方。我会继续尝试一些东西