I have a database and would like to make an app, that displays messages.
In my swift app there's a variable, let's fill it up with some random values
var globalMessages :
{
["uid": 1, "msg": "test1"],
["uid": 2, "msg": "test2"],
["uid": 3, "msg": "test3"],
}
And I fetch these data from the net with urlSession:
{
["uid": 1, "msg": "test1"],
["uid": 10, "msg": "NEW"], //new data
["uid": 2, "msg": "test2"],
["uid": 3, "msg": "test3"]
}
Then I don't wanna reload all the table: I just want to add the ["uid": 10, "msg": "NEW"] new message to the table between the 1. and 2. user's messages, with a gentle animation pushing the two already-there messages.
Is it possible somehow?
The question is which I can't figure out, that how can I check that which items are new in the new fetched data 's array, that are not in the old globalMessages , and if there is some then display it with animation.
And if some item is no longer in the new fetched data , then remove it with animation from the tableview. ??
Currently I am doing this:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return globalMessages.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BubbleCell", for: indexPath) as! BubbleCell
let bubble = globalMessages[indexPath.row]
cell.messageLabel.text = bubble.message
let typeColor = UIColor(rgb: 0xE2E2E2)
if let image = UIImage(named: "bubble") {
let h = image.size.height / 2
let w = image.size.width / 2
cell.bubbleImageView.image = image
.resizableImage(withCapInsets:
UIEdgeInsetsMake(h, w, h, w),
resizingMode: .stretch).withRenderingMode(.alwaysTemplate)
cell.bubbleImageView.tintColor = typeColor.withAlphaComponent(0.85)
}
return cell
}
And using a global timer every 10 seconds the app downloads the datas from the net into the globalMessages array, and then reloads the table with notification push:
@objc func notification_reloadTableView(){
DispatchQueue.main.async(execute: {() -> Void in
let range = NSMakeRange(0, self.tableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
self.tableView.reloadSections(sections as IndexSet, with: UITableViewRowAnimation.fade)
})
}
You can insert it like this
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row:1, section: 0)], with: .automatic)
tableView.endUpdates()
but first append the new data in the array at the correct position
globalMessages.insert(["uid": 10, "msg": "NEW"], at: 1)
You can use a dictionary as a lookup table of sorts:
// For simplicity, I'm pretending you have a "Message" object that
// would be in each element of that array you are using.
// This would be a private class level variable.
var messageLookup: [String : Message] = [:]
// And then later, probably in a method you can do the following:
var newMessages: [Message] = []
var updatedMessageLookup: [String : Message] = [:]
// You just got your new batch of messages, I'll say they're in
// an array called "messages".
for message in messages
{
if messageLookup[message.UID] == nil
{
// It's not in your lookup, so it is new.
newMessages.append(message)
}
// As we enumerate, build up what will become the new lookup.
updatedMessageLookup[message.UID] = message
}
messageLookup = updatedMessageLookup
At the end, the newMessages array will have your, well, new messages.
let's say you have two arrays, newArray
and oldArray
. You iterate the newArray
and check if the item existing in the oldArray
, for those are not, make the indexes as indexPaths, and put them in an array called insertIndexPaths
. The do the same thing to iterate the oldArray
and find out the items not existing and put them in removeIndexPaths
. And finally you call insertRowsAtIndexPaths
or deleteRowsAtIndexPaths
from the tableView
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.