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