我有两种不同的单元格类型,一种用于评论,另一种用于回复。我试图将它们呈现在相同的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)
}
}
}
答案 0 :(得分:2)
最佳实践解决方案
创建一个包含回复对象列表的回复模型和评论模型
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和注释数据列表的CommentViewController类
请注意,标头和单元格已通过viewDidLoad方法注册到集合视图中
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
}
}
让我们看看评论屏幕:)
答案 1 :(得分:0)
如果我错了,请纠正我,您正在尝试制作嵌套单元格,并且每个单元格都有一个标题类型的东西,就像Facebook一样,对吧!
就是这样,评论是在每个部分的标题中,而答复是在单元格中。因此,注释将显示在每个部分的顶部,并回复单元格作为主体。您将需要numberOfSections代表进行评论,并需要numberOfRows代表进行答复。
如果我做错了,请问我。
答案 2 :(得分:0)
所以我基本上要做的是创建一个PostType类,这样当我必须呈现某种单元格类型时,我可以在注释和回复类型之间进行切换。
class PostType {
enum CommentsTypes {
case PostType
case Reply
case Comment
}
var type: CommentsTypes {
get {
return .PostType
}
}
}
将我的“评论和答复”类子类化为PostType,就像这样:
class Comment: PostType {
....
override var type: CommentsTypes {
return .Comment
}
}
class Reply: PostType {
....
override var type: CommentsTypes {
return .Reply
}
}
然后,我提取了一组PostType来保存评论和答复:
var postsTypes: [PostType] = []
//after fetching comments and replies
self.postsTypes.append(contentsOf: comments)
self.postsTypes.append(contentsOf: replies)
最后设置
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return postsTypes.count
}
和
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item = indexPath.item
let post = self.postsTypes[item]
switch post.type {
case .Comment:
let comment = post as! Comment
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CommentCell.cellId, for: indexPath) as! CommentCell
cell.comment = comment
return cell
case .Reply:
let reply = post as! Reply
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RepliesCell.cellId, for: indexPath) as! RepliesCell
cell.reply = reply
return cell
default:
return UICollectionViewCell()
}
}
像魅力一样工作!很高兴我终于找到了问题的答案。感谢大家的建议。