Xây dựng realtime chat sử dụng SendBird SDK và JSQMessagesViewController Part 2
Giới thiệu Tiếp theo phần 1: https://viblo.asia/nguyen.viet.dung/posts/PDOkqXwpejx hôm nay chúng ta sẽ đi tiếp phần 2. Ở part 1 tôi đã giới thiệu cách sử dụng SenbirdSDK tạo 1 ứng dụng chat đơn giản, ở part 2 này tôi sẽ hướng dẫn cách sử dụng thư viện JSQMessagesViewController để custom giao diện ...
Giới thiệu
Tiếp theo phần 1: https://viblo.asia/nguyen.viet.dung/posts/PDOkqXwpejx hôm nay chúng ta sẽ đi tiếp phần 2. Ở part 1 tôi đã giới thiệu cách sử dụng SenbirdSDK tạo 1 ứng dụng chat đơn giản, ở part 2 này tôi sẽ hướng dẫn cách sử dụng thư viện JSQMessagesViewController để custom giao diện chat. OK, let's start!!
Install JSQMessagesViewController
Chúng ta sẽ tạo file pod add line sau đây vào file Pod
pod 'JSQMessagesViewController'
Sau đó dùng terminal để install thư viện
pod install
Ok vậy là chúng ta đã cài đặt xong thư viện, tiếp theo chúng ta sẽ sử dụng thư viện này cho việc hiển thị giao diện màn hình chat
Using JSQMessagesViewController
File ChatViewController chúng ta sẽ cho kế thừa từ JSQMessagesViewController
ChatViewController: JSQMessagesViewController
Khai báo và Khởi tạo ImageBubble:
var inBubble: JSQMessagesBubbleImage? var outBubble: JSQMessagesBubbleImage?
inBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor.jsq_messageBubbleBlueColor()) _outBubble = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
Chúng ta sử dụng JSQMessage là đối tượng lưu trữ message, mảng JSQMessage để lưu trữ mảng các message này:
var messages = [JSQMessage]()
Implement Datasource: 1 số hàm chính mà ta cần chú ý
Hàm đầu tiên trả về số message chat
Hàm thứ 2 sẽ trả về message tương ứng cho các row
Hàm thứ 3 quyết định việc hiển thị outgoing hay incoming bubble bằng việc so sánh senderId ta sẽ biết được cell tương ứng là cell của mình hay cell của bạn chat để hiển thị bubble tương ứng.
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return messages.count } override func collectionView(collectionView: JSQMessagesCollectionView?, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData? { return messages[indexPath.item] } override func collectionView(collectionView: JSQMessagesCollectionView?, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource? { return messages[indexPath.item].senderId == self.senderId ? outBubble : inBubble }
Ở trên chúng ta đã sử dụng JSQMessageTableViewCell mặc định để hiển thị các chat message, dưới dây ta sẽ tìm hiểu cách custom JSQMessageTableViewCell này. Chúng ta sẽ custom 2 loại cell tương ứng là : MessageViewOutGoing, MessageViewIncoming. Tạo 2 class:
class MessageViewIncoming: JSQMessagesCollectionViewCellIncoming
class MessageViewOutGoing: JSQMessagesCollectionViewCellOutgoing
Copy 2 file JSQMessagesCollectionViewCellIncoming.xib và JSQMessagesCollectionViewCellOutgoing.xib sau đó đổi tên thành MessageViewIncoming.xib, MessageViewOutGoing.xib, đặt class cho 2 file này thành MessageViewIncoming, MessageViewOutGoing. Đặt cell identifier tương ứng: MessageViewIncoming. MessageViewOutGoing Bây giờ ta có thể custom giao diện theo í muốn trên 2 file MessageViewIncoming.xib, MessageViewOutGoing.xib Để sử dụng file custom này chúng ta cần register chúng trong viewDidLoad:
override func viewDidLoad() { ... self.collectionView.registerNib(UINib.init(nibName: "MessageViewIncoming", bundle: nil), forCellWithReuseIdentifier: "MessageViewIncoming") self.collectionView.registerNib(UINib.init(nibName: "MessageViewOutGoing", bundle: nil), forCellWithReuseIdentifier: "MessageViewOutGoing") self.incomingCellIdentifier = "MessageViewIncoming" self.outgoingCellIdentifier = "MessageViewOutGoing" }
Sử dụng:
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 // return cell } else { let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! MessageViewIncoming // return cell } }
Enjoy: