首页 > 解决方案 > CollectionView 中用于评论和回复的多个单元格

问题描述

我有两种不同的单元格类型,一种用于评论,另一种用于回复。我试图以相同的方式呈现它们,collectionView然后可能像这样对它们进行分组:每个具有特定 id 的评论都有它的回复。然而,任何尝试,我都失败了。

你会怎么做?

private var comments = [Comment]()
private var replies = [Reply]()
var items: [Any] = []


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//        let item = items[indexPath.item]

        var item = items[indexPath.item]

        if item is Comment.Type  {

            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CommentCell.cellId, for: indexPath) as! CommentCell
            cell.comment = items[indexPath.item] as? Comment
            print(item)
            return cell


        } else {
                    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RepliesCell.cellId, for: indexPath) as! RepliesCell
            cell.reply = items[indexPath.item] as? Reply

                    return cell

        }



    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let item = items[indexPath.item]

        if item is CommentCell.Type {

            let dummyCell = CommentCell(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 50))
            dummyCell.comment = items[indexPath.item] as? Comment
            dummyCell.layoutIfNeeded()

            let targetSize = CGSize(width: view.frame.width, height: 250)
            let estimatedSize = dummyCell.systemLayoutSizeFitting(targetSize)
            let height = max(40 + 8 + 8, estimatedSize.height)

            return CGSize(width: view.frame.width, height: height)
        } else {
            let dummyCell = RepliesCell(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 50))
            dummyCell.reply = items[indexPath.item] as? Reply
            dummyCell.layoutIfNeeded()

            let targetSize = CGSize(width: view.frame.width, height: 250)
            let estimatedSize = dummyCell.systemLayoutSizeFitting(targetSize)
            let height = max(40 + 8 + 8, estimatedSize.height)

            return CGSize(width: view.frame.width, height: height)
        }
     }
}

标签: iosswiftuicollectionviewuicollectionviewcell

解决方案


最佳实践解决方案

创建一个包含回复对象列表的回复模型和评论模型

class Comment {
    var commentId: Int
    var commentText: String
    var replies: [Reply]

    init(commentId: Int, commentText: String, replies: [Reply]) {
        self.commentId = commentId
        self.commentText = commentText
        self.replies = replies
    }
}

class Reply {
    var replyId: Int
    var replyText: String

    init(replyId: Int, replyText: String) {
        self.replyId = replyId
        self.replyText = replyText
    }
}

为评论标题创建一个 UICollectionReusableView

class CommentHeader: UICollectionReusableView {

    @IBOutlet weak var commentTextLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func configure(with comment: Comment) {
        commentTextLabel.text = comment.commentText
    }

}

创建一个 UICollectionViewCell 用于回复

class ReplyCell: UICollectionViewCell {

    @IBOutlet weak var replyTextLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func configure(with reply: Reply) {
        replyTextLabel.text = reply.replyText
    }

}

创建一个具有 UICollectionView 和评论数据列表的 CommentsViewController 类

注意header和cell在viewDidLoad方法中注册到collection view

class CommentsViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    var comments: [Comment] = [Comment]()

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.register(UINib(nibName: "CommentHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "CommentHeaderIdentifier")
        collectionView.register(UINib(nibName: "ReplyCell", bundle: nil), forCellWithReuseIdentifier: "ReplyCellIdentifier")

        comments = getDummyComments(with: 3)
    }

    func getDummyComments(with count: Int) -> [Comment] {

        var comments = [Comment]()
        for i in 1...count {
            comments.append(Comment(commentId: i, commentText: "Comment \(i)", replies: getDummyReplies(with: i)))
        }
        return comments

    }

    func getDummyReplies(with count: Int) -> [Reply] {
        var replies = [Reply]()
        for i in 1...count {
            replies.append(Reply(replyId: i, replyText: "Reply \(i)"))
        }
        return replies
    }
}

最后设置 UICollectionView 数据源和委托方法

extension CommentsViewController: UICollectionViewDataSource {

    // for cell
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return comments.count
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return comments[section].replies.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let replyCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ReplyCellIdentifier", for: indexPath) as! ReplyCell
        replyCell.configure(with: comments[indexPath.section].replies[indexPath.row])
        return replyCell

    }

    // for header
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        if kind == UICollectionElementKindSectionHeader {

            let commentHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CommentHeaderIdentifier", for: indexPath) as! CommentHeader

            commentHeader.configure(with: comments[indexPath.section])
            return commentHeader
        }

        return UICollectionReusableView()
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 100) // this height is used for the example, you can use self sizing for height
    }

}

extension CommentsViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        return CGSize(width: collectionView.frame.width, height: 100) // this height is used for the example, you can use self sizing for height

    }

}

让我们看看评论屏幕:)

在此处输入图像描述


推荐阅读