swift - How to reload UITableView without printing data twice? -
i have single view of slacktextviewcontroller works uitableview. i'm switching between "states" using public string allowing read 1 set of data in state , set of data in state. problem when switch , forth original state prints data 2, 3, 4 times; many go , forth. i'm loading data firebase server , think may firebase issue. here code...
override func viewwillappear(animated: bool) { super.viewwillappear(animated) if chatstate == "all" { self.globalchat() }else if chatstate == "local" { self.localchat() } } override func viewdiddisappear(animated: bool) { self.messagemodels.removeall() tableview.reloaddata() ref.removeallobservers() } func chatactn() { if chatstate == "all" { self.viewwillappear(true) }else if chatstate == "local" { self.viewwillappear(true) } } func globalchat() { self.messagemodels.removeall() tableview.reloaddata() let globalref = ref.child("messages") globalref.keepsynced(true) globalref.querylimitedtolast(100).observeeventtype(.childadded, withblock: { (snapshot) -> void in if snapshot.exists() { let names = snapshot.value!["name"] as! string let bodies = snapshot.value!["body"] as! string let avatars = snapshot.value!["photo"] as! string let time = snapshot.value!["time"] as! int let messagemodel = messagemodel(name: names, body: bodies, avatar: avatars, date: time) self.messagemodels.append(messagemodel) self.messagemodels.sortinplace{ $0.date > $1.date } } self.tableview.reloaddata() }) } func localchat() { self.messagemodels.removeall() tableview.reloaddata() print("local") }
the problem each time call globalchat()
you're creating new observer results in having multiple observers adding same items self.messagemodels
. thats why you're seeing data many times switch global state.
since want clear chat , load last 100 each time switch global, there's no point in keeping observer active when switch "local".
just remove observer when switch local, should fix problem.
from firebase docs:
- (void) removeallobservers
removes observers @ current reference, not remove observers @ child references.
removeallobservers must called again each child reference listener established remove observers.
so, ref.removeallobservers()
not remove observers @ ref.child("messages")
level.
using ref.child("messages").removeallobservers
@ beginning of localchat
function remove observer created in globalchat
ok if you're dealing 1 observer @ level if have more on same level or think might add more in future best , safest way remove specific observer created. should use handle returned starting observer. modify code this:
var globalchathandle : firdatabasehandle? func globalchat() { self.messagemodels.removeall() tableview.reloaddata() ref.child("messages").keepsynced(true) globalchathandle = ref.child("messages").querylimitedtolast(100).observeeventtype(.childadded, withblock: { (snapshot) -> void in if snapshot.exists() { let names = snapshot.value!["name"] as! string let bodies = snapshot.value!["body"] as! string let avatars = snapshot.value!["photo"] as! string let time = snapshot.value!["time"] as! int let messagemodel = messagemodel(name: names, body: bodies, avatar: avatars, date: time) self.messagemodels.append(messagemodel) self.messagemodels.sortinplace{ $0.date > $1.date } } self.tableview.reloaddata() }) } func localchat() { if globalchathandle != nil { ref.child("messages").removeobserverwithhandle(globalchathandle) } self.messagemodels.removeall() tableview.reloaddata() print("local") }
and in viewdiddisappear
method replace this
ref.removeallobservers()
with
ref.child("messages").removeallobservers()
Comments
Post a Comment