导航回 ViewController 时出现重复消息问题
Issue with Duplicate Messages When navigating back to ViewController
我有一个 ViewController 可以向用户显示更多信息,然后他们单击一个按钮并将它们发送到我的 messageView,它是一个 JSQ ViewController。 JSQViewController 使用集合视图 类。当用户导航回到更多信息视图,然后点击按钮再次导航到消息视图时,集合视图复制了我的聊天气泡。我想我需要将某些东西重置为零,但我不确定要设置什么以及在哪里设置。这是我的代码:
import UIKit
import Firebase
import JSQMessagesViewController
// MARK: Properties
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
let rootReference = FIRDatabase.database().referenceFromURL("myHTTPSLINK")
var messageReference: FIRDatabaseReference!
var dataBaseMessageRef: FIRDatabaseReference!
class ChatViewController: JSQMessagesViewController{
var userContacedID: String = ""
var userToBeChatted : String = ""
var userIsTypingRef: FIRDatabaseReference!
var usersTypingQuery: FIRDatabaseQuery!
private var localTyping = false
var isTyping: Bool {
get {
return localTyping
}
set {
localTyping = newValue
userIsTypingRef.setValue(newValue)
}
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Now Chatting With: " + userToBeChatted
setupBubbles()
// No avatars
collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
messageReference = rootReference.child("messages")
dataBaseMessageRef = messageReference.child("\(userToBeChatted)" + "\(FIRAuth.auth()?.currentUser?.displayName)")
print ("This users being messaged is: ", userToBeChatted)
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!,
senderDisplayName: String!, date: NSDate!) {
let itemRef = dataBaseMessageRef.childByAutoId() // 1
let messageItem = [ // 2
"text": text,
"senderId": senderId,
"receiver" : userToBeChatted,
"senderName": FIRAuth.auth()?.currentUser?.displayName,
"receiverID": userContacedID
]
itemRef.setValue(messageItem) // 3
// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()
// 5
finishSendingMessage()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
observeMessages()
observeTyping()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item] // 1
if message.senderId == senderId { // 2
return outgoingBubbleImageView
} else { // 3
return incomingBubbleImageView
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleRedColor())
}
func addMessage(id: String, text: String) {
let message = JSQMessage(senderId: id, displayName: FIRAuth.auth()?.currentUser?.displayName , text: text)
messages.append(message)
}
override func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
as! JSQMessagesCollectionViewCell
let message = messages[indexPath.item]
if message.senderId == senderId {
cell.textView!.textColor = UIColor.whiteColor()
} else {
cell.textView!.textColor = UIColor.whiteColor()
}
return cell
}
private func observeMessages() {
dataBaseMessageRef = messageReference.child("\(userToBeChatted)\(FIRAuth.auth()?.currentUser?.displayName as String!)")
let messagesQuery = dataBaseMessageRef.queryLimitedToLast(25)
messagesQuery.observeEventType(.ChildAdded, withBlock: { snapshot in
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
self.addMessage(id, text: text)
self.finishReceivingMessage()
})
}
override func textViewDidChange(textView: UITextView) {
super.textViewDidChange(textView)
isTyping = textView.text != ""
}
private func observeTyping() {
let typingIndicatorRef = rootReference.child("typingIndicator")
userIsTypingRef = typingIndicatorRef.child(senderId)
userIsTypingRef.onDisconnectRemoveValue()
usersTypingQuery = typingIndicatorRef.queryOrderedByValue().queryEqualToValue(true)
usersTypingQuery.observeEventType(.Value, withBlock: { snapshot in
// You're the only one typing, don't show the indicator
if snapshot.childrenCount == 1 && self.isTyping { return }
// Are there others typing?
self.showTypingIndicator = snapshot.childrenCount > 0
self.scrollToBottomAnimated(true)
})
}
}
在 viewDidAppear 之前 observeMessages()
插入 messages.removeAll()
或 messages = []
将 observeMessages()
从 viewDidAppear()
移动到 viewDidLoad()
。
有同样的问题,并设法用上面的方法解决了它。
我有一个 ViewController 可以向用户显示更多信息,然后他们单击一个按钮并将它们发送到我的 messageView,它是一个 JSQ ViewController。 JSQViewController 使用集合视图 类。当用户导航回到更多信息视图,然后点击按钮再次导航到消息视图时,集合视图复制了我的聊天气泡。我想我需要将某些东西重置为零,但我不确定要设置什么以及在哪里设置。这是我的代码:
import UIKit
import Firebase
import JSQMessagesViewController
// MARK: Properties
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
let rootReference = FIRDatabase.database().referenceFromURL("myHTTPSLINK")
var messageReference: FIRDatabaseReference!
var dataBaseMessageRef: FIRDatabaseReference!
class ChatViewController: JSQMessagesViewController{
var userContacedID: String = ""
var userToBeChatted : String = ""
var userIsTypingRef: FIRDatabaseReference!
var usersTypingQuery: FIRDatabaseQuery!
private var localTyping = false
var isTyping: Bool {
get {
return localTyping
}
set {
localTyping = newValue
userIsTypingRef.setValue(newValue)
}
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Now Chatting With: " + userToBeChatted
setupBubbles()
// No avatars
collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
messageReference = rootReference.child("messages")
dataBaseMessageRef = messageReference.child("\(userToBeChatted)" + "\(FIRAuth.auth()?.currentUser?.displayName)")
print ("This users being messaged is: ", userToBeChatted)
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!,
senderDisplayName: String!, date: NSDate!) {
let itemRef = dataBaseMessageRef.childByAutoId() // 1
let messageItem = [ // 2
"text": text,
"senderId": senderId,
"receiver" : userToBeChatted,
"senderName": FIRAuth.auth()?.currentUser?.displayName,
"receiverID": userContacedID
]
itemRef.setValue(messageItem) // 3
// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()
// 5
finishSendingMessage()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
observeMessages()
observeTyping()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item] // 1
if message.senderId == senderId { // 2
return outgoingBubbleImageView
} else { // 3
return incomingBubbleImageView
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleRedColor())
}
func addMessage(id: String, text: String) {
let message = JSQMessage(senderId: id, displayName: FIRAuth.auth()?.currentUser?.displayName , text: text)
messages.append(message)
}
override func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
as! JSQMessagesCollectionViewCell
let message = messages[indexPath.item]
if message.senderId == senderId {
cell.textView!.textColor = UIColor.whiteColor()
} else {
cell.textView!.textColor = UIColor.whiteColor()
}
return cell
}
private func observeMessages() {
dataBaseMessageRef = messageReference.child("\(userToBeChatted)\(FIRAuth.auth()?.currentUser?.displayName as String!)")
let messagesQuery = dataBaseMessageRef.queryLimitedToLast(25)
messagesQuery.observeEventType(.ChildAdded, withBlock: { snapshot in
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
self.addMessage(id, text: text)
self.finishReceivingMessage()
})
}
override func textViewDidChange(textView: UITextView) {
super.textViewDidChange(textView)
isTyping = textView.text != ""
}
private func observeTyping() {
let typingIndicatorRef = rootReference.child("typingIndicator")
userIsTypingRef = typingIndicatorRef.child(senderId)
userIsTypingRef.onDisconnectRemoveValue()
usersTypingQuery = typingIndicatorRef.queryOrderedByValue().queryEqualToValue(true)
usersTypingQuery.observeEventType(.Value, withBlock: { snapshot in
// You're the only one typing, don't show the indicator
if snapshot.childrenCount == 1 && self.isTyping { return }
// Are there others typing?
self.showTypingIndicator = snapshot.childrenCount > 0
self.scrollToBottomAnimated(true)
})
}
}
在 viewDidAppear 之前 observeMessages()
插入 messages.removeAll()
或 messages = []
将 observeMessages()
从 viewDidAppear()
移动到 viewDidLoad()
。
有同样的问题,并设法用上面的方法解决了它。