简体   繁体   中英

Array & TableView : only add new items

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM