UiCollectionView单个单元格设计

时间:2015-12-02 14:02:40

标签: swift uicollectionview

继续我的UICollectionView学习经历,我被困在最后一期。

我的UIcollection有5个部分,每个部分有8个单元格。我使用selectCellForIndexPath来使用单元格来加载级别,并且在一些社区成员的帮助下,我已经解决了我的一个问题。

我现在遇到的问题是,在解锁上一级别之前,某些单元格应该被锁定。我正在使用bool值来跟踪未锁定的级别。

所以我现在要做的是显示第二个图像,锁定尚未解锁的所有单元格/级别。 我正在使用具有标签和2个图像视图的自定义单元格,其中一个是锁定。在方法cellForItemInIndexPath中,我使用这些bool值来检查单元格是否已解锁,从而隐藏锁定图像。代码看起来像这样

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier.cell, forIndexPath: indexPath) as! CustomCollectionViewCel

// level label    
cell.levelLabel.text = self.cells[indexPath.row]

// main cell image
cell.imageView.image = UIImage(named: self.cellImages[indexPath.section])

// check unlock image 
if indexPath.section == 0 {
        switch indexPath.row {
           case 0:
           if level1Unlocked {
              cell.lockImage.hidden = true
           }
           case 1:
           if level2Unlocked {
              cell.lockImage.hidden = true
           }
           ...
    }
}
if indexPath.section == 1 {
      switch....
     ....
}

我的自定义单元格如下

import SpriteKit

class CustomCollectionViewCell: UICollectionViewCell {

// MARK: - Properties

/// Background
var imageView: UIImageView!
var lockImageView: UIImageView!

/// Header
var levelLabel: UILabel!

// MARK: - Init
override init(frame: CGRect) {
    super.init(frame: frame)

    /// Image
    imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
    imageView.contentMode = UIViewContentMode.ScaleAspectFit
    imageView.userInteractionEnabled = true
    #if os(tvOS)
    imageView.adjustsImageWhenAncestorFocused = true
    #endif
    contentView.addSubview(imageView)

    /// Lock Image View
    lockImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
    lockImageView.image = UIImage(named: "Lock")
    lockImageView.contentMode = UIViewContentMode.ScaleAspectFit
    lockImageView.userInteractionEnabled = true
    #if os(tvOS)
        lockImageView.adjustsImageWhenAncestorFocused = true
    #endif
    contentView.addSubview(lockImageView)

    /// Level label
    levelLabel = UILabel(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
    levelLabel.font = UIFont(name: Label.Font.noteworthy, size: 22)
    levelLabel.textColor = SKColor.whiteColor()
    //textLabel.backgroundColor = UIColor.whiteColor()
    levelLabel.textAlignment = .Center
    levelLabel.center.y = 0 + 30
    contentView.addSubview(levelLabel)
}

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

主要问题如下

1)有些单元格没有显示锁定(我检查上面的代码几次以确保其正确)

2)一旦我开始滚动并回到一个单元格,它显示/没有显示锁定图像,尽管它应该是。

3)我玩弄了删除/添加锁定图像而不是隐藏,但结果是一样的。

我认为它与可重复使用的细胞有关。有人可以帮助我,让我正确的方向,我可以管理持续到你重新加载集合视图数据的单个单元格外观。 我正在以编程方式执行此操作,因为我将集合视图覆盖在SKScene上,因此请不要使用故事板提示。 非常感谢你

3 个答案:

答案 0 :(得分:0)

您所经历的是再生细胞的典型特征。单元格“出列”,因此除非您重新配置它们,否则它们可以显示旧数据或状态。

解决方案:确保在cellForItemAtIndexPath中对所有单元格进行完整配置,包括明确将lockImage.hidden设置为truefalse有必要的。

例如,而不是仅使用if语句

设置为true
cell.lockImage.hidden = level1Unlocked

如果level1Unocked为真,则隐藏,如果不是,则显示

顺便说一下,你为每个级别设置专用变量的设置似乎也是次优设计,但也许这是另一个问题。

答案 1 :(得分:0)

尝试这样做:

// Lazy load your views in your CustomCell.m
lazy var imageView: UIImageView  = {
    var temporaryImage: UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
    contentView.addSubview(imageView)
    temporaryImage.contentMode = UIViewContentMode.ScaleAspectFit
    temporaryImage.userInteractionEnabled = true
    #if os(tvOS)
    temporaryImage.adjustsImageWhenAncestorFocused = true
    #endif
    return temporaryImage
}()


// Remove all the custom stuff that we added to our subclassed cell
func prepareForReuse() {
    super.prepareForReuse()
    imageView.removeFromSuperview()
    imageView = nil
}

然后从init中删除imageView初始化。

重复其他2个组件。 我很久以前就知道这是在没有故事板帮助的情况下创建customCells的最佳方式。

注意:我不习惯斯威夫特,如果我犯了错误,请原谅我

答案 2 :(得分:0)

在玩了这个之后,似乎唯一可靠的解决方案是使用2个自定义单元而不是1个单元并试图隐藏某些标签。 在我的selectCellForItemAtIndexPath方法中,我现在这样做。

 let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier.cell, forIndexPath: indexPath) as! CustomCollectionViewCell

 let cellLocked = collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier.cellLocked, forIndexPath: indexPath) as! CustomCollectionViewCellLocked

我只是根据级别解锁状态返回正确的单元格。