Swift - JSQMessagesViewController - 自定义单元格

Swift - JSQMessagesViewController - cell custom

我从这个了解到您可以通过覆盖此方法来自定义 JSQMessagesViewController 库的单元格:

override func collectionView(collectionView: UICollectionView,  cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
 //Configure your cell here
return //yourCustomCell
}

是否有可能获得示例代码以了解如何实现实际的自定义,包括 JSQMessagesCollectionViewCell 的子class?

例如,我想在消息气泡底部添加一个标签,显示消息发送的时间。

谢谢。

编辑

我创建了一个自定义单元格 class 如下:

class MyCustomCell: JSQMessagesCollectionViewCell {

    var textLabel: UILabel

    override init(frame: CGRect) {

        self.textLabel = UILabel(frame:  CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height/3))
        super.init(frame: frame)

        self.textLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
        self.textLabel.textAlignment = .Center
        contentView.addSubview(self.textLabel)
    }

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

}

自定义单元格是在没有任何 xib 文件的情况下以编程方式创建的。

所以在我的 JSQMessagesViewController 中,我必须声明如下:

override func viewDidLoad() {

    super.viewDidLoad()

    self.collectionView!.registerClass(MyCustomCell.self, forCellWithReuseIdentifier: "MyCustomCell")
}

然后,我可以如下覆盖 cellForItemAtIndexPath 方法:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCustomCell", forIndexPath: indexPath) as! MyCustomCell
    return cell
}

问题是我再也看不到消息和以前的设置了。

我做错了什么?

转到xcode创建一个新文件然后选择Cocoa触摸class并在子class列表中选择

UICollectionViewCell 并将您的自定义单元格名称设为

customCellUICollectionViewCell.swift

之后转到 Mainstoryboard 并将新的 collection 单元格拖到您的视图中

Select 您的单元格,然后在 xcode 的右侧菜单中选择

显示身份检查员

并在自定义 class 中键入您的自定义 class 名称

customCellUICollectionViewCell.swift

您 collection 视图中的最后一件事

override func collectionView(collectionView: UICollectionView,  cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
 let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! customCellUICollectionViewCell
return cell
}

我相信您只是没有设置自定义单元格的文本。为了安全我也会守护

override func collectionView(collectionView: UICollectionView,  cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

  guard let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCustomCell", forIndexPath: indexPath) as? MyCustomCell else {
    print("Could not get my custom cell")
    return UICollectionViewCell()
  }

  let message = messages[indexPath.row] // or what ever your messages are called

  let cell.mainLabel.text = message.text

  return cell
}

这是我设法做到的方式:

1- 创建两个子classes:

  • JSQMessagesCollectionViewCellOutgoing

    import UIKit
    import JSQMessagesViewController
    
    class messageViewOutgoing: JSQMessagesCollectionViewCellOutgoing {
    
        @IBOutlet weak var timeLabel: UILabel!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)        
        }
    }
    
  • JSQMessagesCollectionViewCellIncoming

    import UIKit
    import JSQMessagesViewController
    
    class messageViewIncoming: JSQMessagesCollectionViewCellIncoming {
    
        @IBOutlet weak var timeLabel: UILabel!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)        
        }
    }
    

2- 创建两个 xib 文件,其名称与上面的两个子classes 相关。对于每个文件,在文件所有者占位符中添加相关的自定义 class。

3- Copy/paste 来自 JSQMessagesViewController 库的每个相关 classes 的 xib 模板存储在 Resources 文件夹中,并将您的自定义标签添加到其中。

4- Link 上面

的新子 class 的自定义标签

5- 覆盖以下函数

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let message = self.messages[indexPath.item]

    if message.senderId == self.senderId {

        let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! messageViewOutgoing

        cell.timeLabel.text = localHourFormatter.stringFromDate(message.date)

        return cell

    } else {

        let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! messageViewIncoming

        cell.timeLabel.text = localHourFormatter.stringFromDate(message.date)

        return cell
    }
}

现在标签显示在气泡中。

为了调整气泡的大小以正确显示,还有一些工作要做,但这不是这个问题的目的。

如果有的话请告诉我comment/question。

我收到错误消息:无法从 messageViewOutgoing 转换为 JSQMessagesCollectionViewCellIncoming @sbkl。您是否收到此错误,因为我们无法从父类型转换为子类型?