Search code examples
iosarraysswiftuicollectionviewuicollectionviewcell

How to create a new cell in UICollectionView when a new string is added to an array


I have a UICollectionView with the cell count being equal to the number of strings in a certain array.

When I append a new string to the array, I am expecting it to create a new cell, but it does not.

func addDateToArray(dateString: String) {
    Globals.datesArray.append(dateString)
    NSUserDefaults.standardUserDefaults().setObject(Globals.datesArray, forKey: "saveddates")
} 

I am appending from another view

    @IBAction func SetDate(sender: AnyObject) {

    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    let day = dateTimePicker.date
    let datestring = dateFormatter.stringFromDate(day)
    addDateToArray(datestring)

I don't know why this doesn't work. If I haven't been specific enough, let me know to provide more info.


Solution

  • To add a new cell, you can reloadData() and it would work! --- but it is very inefficient :( You just want to update one item and not the whole collectionView (imagine if 1000 items in collection view are loaded to just add 1001th item). So there must be something better

    That is why, we have insert function, and to use it -> you can try something like this after appending. :

    let count = yourStringArray.count  // updated Count of array
    let index = count > 0 ? count - 1 : count  // find the index, where you want to add the item.
    let indexPath = NSIndexPath(forItem: index, inSection: 0)  // make an indexPath out of the found index! 
    collectionView!.insertItemsAtIndexPaths([indexPath]) // This will call dataSource methods itself
    // And you should be good to go! 
    

    Ask questions, if any doubt :-)

    Edit: Code to update Collection View from another class

    Carrying on with suggestions in the comment, you can add observer in you collectionView class like so in viewDidLoad:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourCollectionViewController.loadList(_:)),name:"load", object: nil)
    
    // And add this function in class
    func loadList(notification: NSNotification){
    
        let count = yourStringArray.count
        let index = count > 0 ? count - 1 : count
        let indexPath = NSIndexPath(forItem: index, inSection: 0)
        collectionView!.insertItemsAtIndexPaths([indexPath])
    
    }
    

    Then in your other class you can do this:

    NSNotificationCenter.defaultCenter().postNotificationName("load", object: nil)
    

    Extra: Take a note, that you can send objects through notifications. You can send objects and append to array in the collection view class itself

    like so? :

    NSNotificationCenter.defaultCenter().postNotificationName("load", object: someDateasStringType)
    

    And then you can receive this date and append in the very class(your collectionview class) like so:

    func loadList(notification: NSNotification){
       let returnedDate = notification.object as! String  
    // convert string to Date. and append and insert to collection View (all mentioned above.)
    }