使用'.reloadItems'

时间:2019-01-02 21:23:59

标签: swift uicollectionview uicollectionviewcell

我一直在使用UICollectionView.reloadData()来动态更新单元格,并且效果很好,尽管这会使动画非常笨拙。我迷上了func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell并执行逻辑以确定单元格UI。

这是方法代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RepCollectionViewCell", for: indexPath) as! RepCollectionViewCell

        let mask = CAShapeLayer()
        let path = UIBezierPath(arcCenter: CGPoint(x: cell.bounds.midX, y: cell.bounds.midY),
                                radius: cell.bounds.width / 2, startAngle: -CGFloat.pi / 2, endAngle: 2 * .pi, clockwise: true)

        path.close()

        mask.frame = cell.bounds
        mask.path = path.cgPath

        var alpha = 1.0
        var color = UIColor.white
        var size = 0.0

        switch reps[indexPath.row] {
        case currentRep + 3:
            size = FONT_SIZE / 4
        case currentRep + 2:
            size = FONT_SIZE / 3
        case currentRep + 1:
            size = FONT_SIZE / 2
        case currentRep:
            color = .green
            size = FONT_SIZE
        case currentRep - 1:
            size = FONT_SIZE / 2
            alpha = 0.75
        case currentRep - 2:
            size = FONT_SIZE / 3
            alpha = 0.50
        case currentRep - 3:
            size = FONT_SIZE / 4
            alpha = 0.25
        default:
            color = .clear
            alpha = 0
        }

        cell.layer.mask = mask
        cell.repCount.text = String(reps[indexPath.row])
        cell.backgroundColor = color
        cell.repCount.font = UIFont(name: FONT_NAME, size: CGFloat(size))
        cell.alpha = CGFloat(alpha)

        return cell
    }

现在如上所述,使用UICollectionView.reloadData()时可以正确设置Alpha,但是当我使用UICollectionView.reloadItems(at: [IndexPaths])方法并传递indexPaths数组时,Alpha单元格不会更新。但是,背景颜色,字体大小,contentView alpha等将会更新。

这是我用来生成需要更新的单元格的indexPath和后续调用的代码。

private func focusCollectionView()
    {
        self.MyUICollectionView.reloadItems(at: generateIndexPaths())
        self.MyUICollectionView.scrollToItem(at: IndexPath(item: myVar - 1, section: 0), at: UICollectionView.ScrollPosition.centeredHorizontally, animated: true)
    }

    private func generateIndexPaths() -> [IndexPath]
    {
        var indexPaths = [IndexPath]()

        if(myVar - 4 >= 0)
        {
            indexPaths.append(IndexPath(row: myVar - 4, section: 0))
        }
        if(myVar - 3 >= 0)
        {
            indexPaths.append(IndexPath(row: myVar - 3, section: 0))
        }
        if(myVar - 2 >= 0)
        {
            indexPaths.append(IndexPath(row: myVar - 2, section: 0))
        }
        if(myVar - 1 >= 0)
        {
            indexPaths.append(IndexPath(row: myVar - 1, section: 0))
        }

        indexPaths.append(IndexPath(row: myVar, section: 0))

        if(myVar + 1 < _myOtherVar)
        {
            indexPaths.append(IndexPath(row: myVar + 1, section: 0))
        }
        if(myVar + 2 < _myOtherVar)
        {
            indexPaths.append(IndexPath(row: myVar + 2, section: 0))
        }
        if(myVar + 3 < _myOtherVar)
        {
            indexPaths.append(IndexPath(row: myVar + 3, section: 0))
        }

        return indexPaths
    }

这是两个结果的演示,第一个使用'reloadData',第二个使用'reloadItems':https://imgur.com/a/ECOnYIj

我不知道为什么会这样,如何解决它,有什么想法吗?

1 个答案:

答案 0 :(得分:1)

据我了解,背景色应该显示出来吗?还是我误解了意图?

因此,使用您的代码进行测试似乎未应用该单元格的Alpha,请参见

view

想法

将单元格的backgroundColor设置为.clear可以使我们使用contentView的Alpha,并且仍然可以看到背景。

进行测试

在我使用的UICollectionViewController子类中:

self.collectionView.backgroundColor = .black

我在这里稍加修改了您的代码(如rmaddy在他的回答中建议的那样):

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
...
cell.myLabel.text = String(reps[indexPath.row])
cell.contentView.alpha = 1
...

然后分别更改

  • cell.backgroundColor =cell.contentView.backgroundColor =

  • cell.alpha =cell.contentView.alpha =

在MyUICollectionViewCell中,将单元格的backgroundColor设置为UIColor.clear:

self.backgroundColor = .clear

除此之外,CollectionViewCell的代码相当有趣,这里仅供参考:

class MyUICollectionViewCell: UICollectionViewCell {

    let myLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = .clear
        self.contentView.addSubview(self.myLabel)
        self.myLabel.textAlignment = .center
        self.myLabel.snp.makeConstraints { (maker) in
            maker.edges.equalToSuperview()
        }
    }

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

}

在我的测试案例中,myVar是所选项目的索引,因此我在scrollToItem中删除了-1,因此它看起来像这样:

private func focusCollectionView()
{
    self.collectionView.reloadItems(at: generateIndexPaths())
    self.collectionView.scrollToItem(
        at: IndexPath(item: myVar, section: 0),
        at: .centeredHorizontally,
        animated: true)
}

演示

因此,在模拟器中对其进行测试时,它看起来像这样:

Testing in Simulator

这是您要找的吗?