如何正确管理精心制作的Collection View cellForItemAt方法?

问题描述

我是一个相当新的开发人员,我有一些很长的cellForItemAt方法。我感觉自己缺少一些重要的东西。

在此ViewController中,我有一个分段控件,该控件使用布尔taskView属性过滤数据。

这是我的cellForItemAt调用的样子:

func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TaskCell.reuseIdentifier,for: indexPath) as! TaskCell
        
        //SwipeCell Delegate
        cell.delegate = self
        
        var transactionResults: Results<Transaction>
        
        if taskView {
            transactionResults = unclearedTransactionsToDate
        } else {
            transactionResults = allTransactions
        }
        
        cell.configureCollectionViewCells(indexPath,transactionResults)
        
        let balanceAtDate: Double = realm.objects(Transaction.self).filter("transactionDate <= %@",transactionResults[indexPath.item].transactionDate).sum(ofProperty: "transactionAmount")
        
        cell.balanceLabel.attributedText = balanceAtDate.toAttributedString(size: 9,offset: 6)
        
        if transactionResults[indexPath.item].isCleared == false && !taskView {
            cell.amountLabel.textColor = .lightGray
            cell.subcategoryLabel.textColor = .lightGray
            cell.dateLabel.textColor = .lightGray
            cell.balanceLabel.textColor = .lightGray
            cell.circleView.backgroundColor = .lightGray
        } else {
            cell.subcategoryLabel.textColor = .black
            cell.dateLabel.textColor = .black
            cell.balanceLabel.textColor = .black
            cell.circleView.backgroundColor = UIColor(rgb: transactionResults[indexPath.item].transactionCategory!.categoryColor)
        }
        
        return cell
    }
}

在我的configureCollectionViewCells方法中,我有

func configureCollectionViewCells(_ indexPath: IndexPath,_ transaction: Results<Transaction>) {
        
        imageView.image = UIImage(named: transaction[indexPath.item].transactionCategory!.categoryName)
        imageView.tintColor = .white
        circleView.backgroundColor = UIColor(rgb: transaction[indexPath.item].transactionCategory!.categoryColor)
        subcategoryLabel.textColor = .black
        dateLabel.textColor = .black
        balanceLabel.textColor = .black
        subcategoryLabel.text = transaction[indexPath.item].transactionSubCategory?.subCategoryName
        amountLabel.attributedText = transaction[indexPath.item].transactionAmount.toAttributedString(size: 9,offset: 6)
        
        
        
        let formatter = DateFormatter()
        
        formatter.dateFormat = "MMMM dd,yyyy"
        
        let dateString = formatter.string(from: transaction[indexPath.item].transactionDate)
        
        dateLabel.text = dateString
        
        if transaction[indexPath.item].transactionAmount > 0 {
            
            amountLabel.textColor = UIColor(rgb: Constants.green)
            
        } else {
            
            amountLabel.textColor = UIColor(rgb: Constants.red)
            
        }
    }

代码有效,但是我感觉它没有正确实现。有人可以给我一些有关如何管理如此冗长功能的建议(请记住,我是编程新手)吗?我觉得我缺少几个概念。

有些人刚刚说过“将所有内容都扔到cellForItemAt中”,有些人在cellForItemAt中只有3行。

我认为也许我应该重写collectionView单元格中的layoutSubviews方法,并在那里实现一些代码

任何一般或特定建议,我们将不胜感激。我也将有兴趣研究是否有人对此主题有任何资源。

谢谢。

解决方法

您正在做的事情本身并不是“错误”。但是,有一种观点认为,cellForRowAt理想情况下应该不了解单元格的内部接口。这(cellForRowAt)是数据源。它应该只将单元格的 data 传递给单元格。您有一个单元格子类(TaskCell),因此它只需要一些方法或属性就可以告诉他们数据是什么,然后该单元格应自行格式化并根据这些设置填充其自己的接口。

如果将所有格式和配置代码都移到单元格子类中,则cellForRowAt实现将更短,更清晰,更清晰,并且分工将更合适。

为了支持这一理念,我只想补充一下,Apple已在iOS 14中采用了它,其中一个单元格现在可以具有UIContentConfiguration对象,该对象的任务是将数据从cellForRowAt传递到{ {1}}的单元格。因此,例如,您不是说contentView(对于表视图单元格)而是说cell.textLabel.text = "howdy",而是让配置对象担心UILabel可能包含在界面中。>