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。您是否收到此错误,因为我们无法从父类型转换为子类型?
我从这个
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。您是否收到此错误,因为我们无法从父类型转换为子类型?