Inserting posts into a UICollectionView grid?

时间:2016-07-11 20:02:26

标签: ios swift firebase uicollectionview firebase-realtime-database

Need some guidance on how to approach this. I'm not sure if I'm completely over complicating it or if it is a mess.

I've got a UICollectionView that I want to always have 9 cells and I'm wanting users to be able to insert posts by tapping on a cell..so if they press on cell 8, they make their post, and it shows up there in the 8th cell with potentially 8 other empty cells around it.

I'm posting/pulling these posts from firebase...so I was thinking the flow needed to look something like:

1) Make an empty array of 9 empty [Posts] so that the cells appear and are clickable.

2) On the firebase observer .. if there are say 3 posts able to be returned, it inserts them into the post array / replaces 3 empty posts.

3) I want the posts to show up sort of randomly throughout the grid, so I figured I'd shuffle the array before reloading the data?

4) I don't really care if the posts back from firebase are in the same spot as they were placed by the user, but I want when a user puts a post for it to stay in the same spot as they placed it, so I figured I'd save a variable to firebase like "position : 8" and I'd say something like "If your user uid = the uid of the post, grab the position number and insert that post at that index of the array.

Is this flow way off base or is there a better way to accomplish this? I haven't seen much about inserting items into certain positions into a table view/collection view.

Edit:

func fillWithBlanks() {
        for i in 0  ..< 9 {

            let blankPost = Post(timestamp: 99999999999999999, picURL: nil, postKey: "") // 100% need a better timestamp there, just filler for now.

            postsArray.append(blankPost)

        }
    }

and then

DataService.ds.REF_POSTS.queryOrderedByChild("timestamp").queryStartingAtValue(cutoff).observeEventType(.ChildAdded, withBlock: { (snapshot:FIRDataSnapshot) in


    let time = snapshot.value!["timestamp"] as? Int
    let text = snapshot.value!["text"] as? String
    let picURL = snapshot.value!["imageURL"] as? String
    let key = snapshot.key

    let post = Post(timestamp: time!, picURL: picURL!, postKey: key)

    self.postsArray[self.selectedPostIndex] = post

    self.collectionView.reloadData()

})

So basically on viewDidLoad I'm calling fillWithBlanks(), and then when I select a cell I set the selectedPostIndex to the index clicked on, create a post, and insert it in where I selected.

This works and I tested it by printing out the cell's timestamp when I press on it, and sure enough when I make a post the timestamp is appropraite to the post and not the 99999999.

My massive issue I'm having are the pictures. When I load up I get 9 cells that are empty but when I make a post it sets the picture I set for the post to all 9 cells, and then if I make 2 posts, I get a very Simon-says'ie flashing in all of my cells between the first picture, second picture, and the blank background from the blank cell.

When I make a post I'm saving a download url to firebase and then I have a caching system that downloads the posts or grabs them in. It all worked before trying to implement the blank posts.

Any ideas what would be causing that? I don't understand why appending a new post would do anything to the blank posts I'm making when the app loads up. I'm assuming I'm having some misunderstanding with classes and my Post array/ Post objects aren't what they need to be.


Edit 2:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let post = postsArray[indexPath.row]

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MainCell", forIndexPath: indexPath) as! PostCell

    if let imageURL = post.picURL {

        cell.cellImage.loadImageUsingNSCache(imageURL)


    }

    return cell

}

and the .loadimagesUsingNSCache comes from :

extension UIImageView {

func loadImageUsingNSCache(urlString: String){


    if let cachedImage = imageCache.objectForKey(urlString) as? UIImage {
        self.image = cachedImage
        return
    }
        let url = NSURL(string: urlString)
        NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in

            if error != nil {
                print(error)
                return
            }
            dispatch_async(dispatch_get_main_queue(), {

                if let downloadedImage = UIImage(data: data!) {

                    imageCache.setObject(downloadedImage, forKey: urlString)


                    self.image = UIImage(data: data!)
                }





            })


        }).resume()
    }

1 个答案:

答案 0 :(得分:2)

关于图片的问题,请记住集合视图单元格是可重复使用的项目,因此您需要在每次调用collectionView(cellForItemAtIndexPath)时告诉每个项目的内容。

这意味着您需要每次都为cell.cellImage提供一个值,即使post.picURLnil。在这种情况下,您可以说cell.cellImage = nil或显示默认的空白图片。