Grid View vs List View
Instagram Firebase
Sometimes it helps to have a different view of information available with the flick of a switch. In this lesson, let's see how we can easily use our Post Cells from the Home Feed to enable a list view instead of a grid view of our posts.

Comments (43)
Maciek Górecki
6 years ago
Quick noobie question. I noticed that you are declaring the delegate as var, not weak var. Any specific reason for that? There's not going to be a retain cycle?
Brian Voong
6 years ago
Mustafa Sahin
6 years ago
Hi, if purchase this course can we download it?
Mustafa Sahin
6 years ago
I mean can we download the entire completed project?
Te-Jen Wu
6 years ago
Hi Brian, thanks a lot for these awesome courses. I am wondering if you will add the pagination technique course in this video session.
Brian Voong
6 years ago
Te-Jen Wu
6 years ago
Thanks. We are looking forward it.
faraz
6 years ago
Is this the last lesson? :(
Brian Voong
6 years ago
faraz
6 years ago
Alright Brian, these lessons are great, thanks so much. Have fun on your break!
Hen Shabat
6 years ago
Thank you!!!!! Amazing course!!!!!
Dustin Doosun Yang
6 years ago
Maybe it will be nice if we can add real time message chat functionality to instagram app for the next lessons
mathew
6 years ago
It would be cool if you showed how to include videos, in addition to pictures, on the Instagram app for the to be determined section. Thanks!
nikolai_georgie
6 years ago
Adding videos to the project would be amazing.
nikolai_georgie
6 years ago
Nah google cloud functions
yannsonnboys
6 years ago
Dear Briam Thank you so much for this amazing tutorial. It will be great if you can add the options here below on the next video. - Making video post - Voting system (rating systeem) -
rogerbayarea
6 years ago
I guest we should have AR. Instagram update adds Snapchat-style AR face filters. https://9to5mac.com/2017/05/16/instagram-update-face-filters/?pushup=1
Esat Kemal Ekren
6 years ago
I think we can focus notification progress of this app
omari
6 years ago
Hello Brian, the screen with heart Icon is completely empty black screen :S :S
omari
6 years ago
Hello Brian, if you click the image of your post in your userprofileController it should open a new view where the image appears bigger and the comment is below. Also delete options etc are necessary
omari
6 years ago
Please Brian Could you add more lessons we are waiting so much for it to complete our Instagram demo that works with the minimum of features like : important key features: --> How can you block a user in our Instagram app --> How can you edit your profile and save that information --> iOS notifications: if someone liked you post or commented on your post or tries to follow you and Delete Posts and see post details in the userProfileController --> The most important feature for this app is the hashtag feature and searching for hashtags. This is what made Instagram so successful and is also part of other applications. Not so important but nice to have: --> If you create the app the home feed is empty. It would be nice to have some suggestion based on the location or etc. who a user could possibly follow --> User forgets password (Send email etc.) --> User tries to login or register and has wrong credentials. Notify the user about his mistakes like email is not valid etc (maybe with red color =)
Stephan Dowless
6 years ago
Please do suggested followers and pagination!
juliolocoh
6 years ago
Brian don't forget to work on number of like label, post, following and followers. Thks
Jesus Adolfo
6 years ago
Hey Brian, I want to say thank you for the excellent content. I throughly enjoyed the series and can't wait for the next one. This was money well spent and wether or not some bonus content comes later on, I will be happy with what was offered. I hope that for the next series you take some of our input to focus on certain functionalities. Regards!
juliolocoh
6 years ago
please show us to record a video and post it
Vartis
6 years ago
I agree !
rogerbayarea
6 years ago
I guest by this time with need you to have a Kotlin version of Instagram with an AR Augmentation too ;) that will be awesome. On the other hand we hope you have a great trip! until then have a good vacation.
nikolai_georgie
6 years ago
It would be awesome to implement firebase cloud functions for this app.. like when a user likes your post, updating the notification page with the correct information.
omari
6 years ago
That would be awesome
AnthonyBaker
6 years ago
Yea thats forsure a good feature to add
shender ramos
6 years ago
yes i've been trying to get this done, and i cannot get it right either...
saif_ali
6 years ago
Hi, Brian I tired to implement a block user option but I couldn't get it to work right. I made it work to the point where you can't see the blocked user's posts on the feed but the user still Show in the search view. Can you please help me out with that
omari
6 years ago
Hey Brian, it makes it so hard to code because firebase always skips code because of its asynchronous nature. For example I want to implement an activityIndicator in the UserProfileController but it should stopAnimating when the data is finished with loading. But it always skips the code. Can you please show us how to implement an activityIndicator inside of the UserProfileController which will be replaces with the settings button in the navBar once it is finished.
omari
6 years ago
And also how to refresh the userprofilecontroller. If you scroll down the image in grid or list view more and more images appears
Stephan Dowless
6 years ago
Please do pagination! This app wouldn't work well for a large user base without this feature. I've been trying to figure out how to do it with firebase and i'm completely stumped.
omari
6 years ago
Yes I agree, but also the refresh of the Homecontroller is not working well. Also It would be nice if you scroll down it to see how more and more images are loading. Another point we also should considering what happens if we have no internet connection.
Casey West
6 years ago
I agree think this would be very useful
Zash
6 years ago
Hey Brian, it would be great if you could include a session about when a user deletes his account that every post and every comment belonging to this user gets deleted from firebase. Thanks :)
Lord Raim
6 years ago
hi Brian, do not forget about firebase migration in additional video please! best regards!
Hyun Jung Park
6 years ago
Hi, Brian. Thank you for your video course. I learn a lot from this course about building an app! This is my favorite cause. :) I'm looking forward to uploading the next video. Thanks in advance.
Casey West
6 years ago
Researching pagination for the HomeController and finding some information. Praying for tutorial :) This was an incredible course!
Stephan Dowless
6 years ago
Hey Casey, Could you share what you have found? I've been pretty stumped on this
saif_ali
6 years ago
yes please help us out
Casey West
6 years ago
I wasn't able to get it working but still researching. if i find anything i will post here. Hopefully we get a video from Brian about this, as it is vital to making the app more market ready.
Stephan Dowless
6 years ago
I agree. I talked to him and he said its tricky, but he will try and figure out a way to make paginating the home feed simple
victor
6 years ago
I guess we can conform the HomePostCellDelegate protocol in UserProfileController to enable didTapComment() and didLike() to work as well in listView...
mattnet
6 years ago
Hi victor or Brian...did you ever get this one sorted? I tried this, but it says I need to add the didTapComment and didLike functions to my UserProfileControler. Did this work for you? I would think we may want to refactor so we don't have the code in two places..in any case, copying those functions over didn't seem to work for me...
victor
6 years ago
HI Mattnet, apologies for my late reply. Yes, indeed. Both your HomeController and UserProfileController need to implement the protocol delegate "HomePostCellDelegate" which comprises 2 methods: 1. func didTapComment(post: Post) 2. func didLike(for cell: HomePostCell) Besides having those two functions in UserProfileController, you'll need the class to conform to HomePostCellDelegate as well. That is..: class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UserProfileHeaderDelegate, HomePostCellDelegate {..} Hope this helps. The code worked well for me.
mattnet
6 years ago
Ok thanks Victor. So I've done what you suggested in your reply, but when i click the 'comment' icon in list view, it only runs the print statement from the HomePostCell and doesn't appear to be 'delegating' to the didComment function in my UserProfileController. Same outcome with clicking the 'like' icon. Anything extra you may have done beside a straight cut and paste of those two function from HomeController to UserProfileController?
victor
6 years ago
Hi Mattnet, Did you make a reference to the delegate in HomePostCell? var delegate: HomePostCellDelegate? If you do that, the protocol delegate methods in UserProfileController should work... ;) provided you implemented HomePostCell the way Brian instructed ...
victor
6 years ago
oh yes. and hopefully you implemented the switching for GridView in cellForItem in UserProfileController's collectionView: override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { if isGridView { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserProfileCustomCell cell.post = posts[indexPath.item] return cell } else { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: homePostCellId, for: indexPath) as? HomePostCell cell?.post = posts[indexPath.item] cell?.delegate = self return cell! } }
mattnet
6 years ago
Thanks Victor! I had all that, but was missing the line 'cell?.delegate = self' in your reply. I added that and now the comments part is working as expected; however my 'like' button isn't working. Shouldn't it be syncing with same likes from the userprofile list? or did you have to do something extra to make that work correctly? Thanks for the help! Very much appreciated!!
mattnet
6 years ago
Actually comments are opening that view controller, but not loading any comments that were already loaded...so neither likes or comments are working yet...any help much appreciated...?
victor
6 years ago
Hey Mattnet, did you set the delegate for self in the handleLike functions in HomePostCell? func handleLike() { print("Handling Like from within cell..") delegate?.didLike(for: self) }
mattnet
6 years ago
Yes i did that for sure. It seems not to be recognizing the post I'm selecting because when it gets to the line 'guard let postId = post.id else { return }' postId is equal to nil. However, in the HomeControllerView, comments works as expected, Likes work as expected. No issues there. Only in the UserProfileController?
victor
6 years ago
can't really tell what's wrong without looking at your code. Might be good to download our sensei's code and see what's missing in yours. Sorry about that.
mattnet
6 years ago
No worries. I would do that except he didn't do that part in his code. Everything he has done works fine for me, just delegating the UserProfileController with HomePostCell is giving me trouble. I'll put it on the backburner as I try to incorporate some other features. Appreciate the help!
mattnet
6 years ago
Victor, I got it all sorted. It turns out I had to do some more work in the function that fetches my posts in UserProfileController. It too needed the isGridView if/then statements to properly populate likes and comments correctly, Once I got those functioning the same, everything works now. Thanks for the efforts!
victor
6 years ago
Thanks Matt. actually I just tried implementing the same too, but I couldn't figure out how to populate and sync the likes and comments in the post for UserProfileController. Can you show us how you did it? Thanks :)
mattnet
6 years ago
Hi Victor, This is what worked for me....basically taking the same logic from the HomeViewController that handles the likes and comments and adding it into a check of IsGridView...hope this helps....sorry for the delay! fileprivate func fetchOrderedPosts(user: AppUser) { if isGridView { let ref = Database.database().reference().child("posts").child(user.uid) ref.observeSingleEvent(of: .value, with: { (snapshot) in self.collectionView?.refreshControl?.endRefreshing() guard let dictionaries = snapshot.value as? [String: Any] else { return } dictionaries.forEach({ (key, value) in guard let dictionary = value as? [String: Any] else { return } var post = Post(user: user, dictionary: dictionary) post.id = key Database.database().reference().child("likes").child(key).child(user.uid).observeSingleEvent(of: .value, with: { (snapshot) in if let value = snapshot.value as? Int, value == 1 { post.hasLiked = true } else { post.hasLiked = false } self.posts.append(post) self.posts.sort(by: { (p1, p2) -> Bool in return p1.creationDate.compare(p2.creationDate) == .orderedDescending }) self.collectionView?.reloadData() }, withCancel: { (err) in print("Failed to fetch like info for post:", err) }) Database.database().reference().child("likes").child(key).child(user.uid).observe(.childChanged, with: { (snapshot) in if let value = snapshot.value as? Int, value == 1 { post.hasLiked = true } else { post.hasLiked = false } self.collectionView?.reloadData() }) }) }) { (err) in print("Failed to fetch posts:", err) } } else { let ref = Database.database().reference().child("posts").child(user.uid) self.collectionView?.refreshControl?.endRefreshing() //perhaps later we will add some pagination of data ref.queryOrdered(byChild: "creationDate").observe(.childAdded, with: { (snapshot) in guard let dictionary = snapshot.value as? [String: Any] else { return } //guard let user = self.user else { return } let post = Post(user: user, dictionary: dictionary) self.posts.insert(post, at: 0) self.collectionView?.reloadData() }) { (err) in print("Failed to fetch ordered post:", err) } } }
victor
5 years ago
hey Matt, That's awesome! Thanks and sorry for the late reply. Been away working on other projects for a while. :)
GeminixClown
6 years ago
What a great adventure Brian... Great technic as always.... By the way... i voted for pagination too like the others, i know is tricky but i hope u can show us how to do it right.
Stephan Dowless
6 years ago
I have figured out how to do pagination and have it working! Reply to this post if you're interested in how i did it
andrew9bernard
6 years ago
That would be awesome to see.
GeminixClown
6 years ago
wow great, can u tell me how to do pagination?
Stephan Dowless
6 years ago
Email me at dowless.stephan@gmail.com
bokafor90
6 years ago
Really nice work. I learned a lot. Thanks and keep it up!
juliolocoh
6 years ago
Brian when the rest of the videos are going to be available?
Brian Voong
6 years ago
c_pomales
6 years ago
Hey Brian, i have a problem when touching the grid or list button. The method handleChangeToListView is not being called. I have it set to a lazy var and i added the target to both buttons. Please help
Brian Voong
6 years ago
benpalmer661
5 years ago
When i refresh the view in home controller i get this error Handling refresh.. fatal error: Index out of range
Brian Voong
5 years ago
benpalmer661
5 years ago
i just added if posts.count != 0 { cell.post = posts[indexPath.item] } and seems to work ? done in cell for item as seen below override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! HomePostCell if posts.count != 0 { cell.post = posts[indexPath.item] } cell.delegate = self return cell }
albaqawi
5 years ago
this is an awesome workaround. thank you
Maxnelson997
5 years ago
I find this a better implementation of storing project colors. static var mainBlue: UIColor { return UIColor.rgb(red: 17, green: 154, blue: 237) } You can call it like so: view.backgroundColor = .mainBlue
Brian Voong
5 years ago
Maxnelson997
5 years ago
Ill be using that implementation now. thanks! so clean! #minimal
pazarbas
5 years ago
Hello Brian, Thanks for the amazing lecture.. i have a problem, instead of switching to list view through button i change the header height. but because it is a lazy var i need to re-initialize it i couldn't find any solution by now. Is there a easy way to to it. Thanks in advance
Brian Voong
5 years ago
Drew Pasma
5 years ago
Hello Brian, Was wondering if in any of the videos you show how to count and print the amount of posts a user has? Please let me know because that would be extremely helpful. Thank you
Abhishesh
5 years ago
remember, total posts is just posts.count in your Controller file. Make an object in you User struct to hold that value and use that to update the label. In User Struct: var totalPosts: Int? In Controller: user?.totalPosts = posts.count In UserHeader: var total: Int = 0 inside didSet : guard let totalPosts = user?.totalPosts else { return } total = totalPosts updateTotalPostsFollowersFollowing() then make a new func that will set the text instead of setting the text while creating the label. func updateTotalPostsFollowersFollowing(){ let attributedText = NSMutableAttributedString(string: "\(total)\n", attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 14)]) attributedText.append(NSAttributedString(string: "posts", attributes: [NSAttributedStringKey.foregroundColor: UIColor.lightGray, NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14)])) postsLabel.attributedText = attributedText } there might be better solutions but I just tried this when I saw your question :)
cesarvelascou
5 years ago
I did the same thing! Any ideas on how to do something similar with "following". I´ve tried using an observer similiar to what we´ve done on fetchFollowingUserIds and adding a var for following, but all I can do is fetch the currentUser´s followers. Can´t seem to find a way to also fetch the other users´ followers correctly. In User struct: var totalFollowing: Int? In Controller: (Basically the same thing we already had plus a following counter) var following: Int = 0 fileprivate func fetchFollowingUserIds() { guard let uid = Auth.auth().currentUser?.uid else {return} Database.database().reference().child("following").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in guard let userIdsDictionary = snapshot.value as? [String: Any] else {return} userIdsDictionary.forEach({ (key, value) in Database.fetchUserWithUID(uid: key, completion: { (user) in self.following += 1 print("FOLLLLLLLOWING\(self.following)") }) }) }) { (err) in print("Failed to fetch following user ids", err) } } ***So this will work for the current user, but I can´t seem to find a way to change the function to make it more general, so that it can fetch the other users´ following number too. Any ideas? I´m not particularly good with Firebase...
Abhishesh
5 years ago
followers/following branches in database has to be created simultaneously. So to count the total, it really depends on how you created the branches. My implementation is: Following/Followers -> UserId -> list of userID who are followers or the user is following. To get the total, you just have to go to "following"->userID then count the number of children.
wealthnut79
5 years ago
Hey Brian i am attempting to use my own iphone as the simulator i've gone thru the process of signing in with my Apple ID but when i run the simulator i keep getting this error...can you or anyone else in the forum help with this? /Users/GODSTAR/Library/Developer/Xcode/DerivedData/Slack_Is_Talk_Podcast-fisajvjmjacemjexsjoxgqsaewmi/Build/Products/Debug-iphoneos/Slack Is Talk Podcast.app/Frameworks/GoogleToolboxForMac.framework: No such file or directory the apps runs perfectly with the xcode simulator
azhar
4 years ago
The profile image is not loading when switching to list view. Not sure why
malrhex
4 years ago
Did you use the collectionView.reloadData on the delegate of the listView? like this: func didChangeToListView() { isGridView = false collectionView.reloadData() }
Dino32
4 years ago
Hi Brain! I do not why but one problem suddenly appears. When I refreshing the posts (drag down) the simulator is crashing down with an error in Xcode "Index out of range"
Dino32
4 years ago
Brian, I will try to describe a behavior of an error "Index out of range". If I drag down a feed very slowly the problem with refreshing posts is not appears, but if I drag down fast the post feed the app will crashed. Please could you give me a tip how to fix it?
Dake
4 years ago
Hi Brian, how are you? My question is , if I want the same functionality in listView as in the HomeFeed, I mean commenting and liking, how can I implement it?
MehmetEmre
4 years ago
Hi Brain thank you for course. My question is, if we have two different type of item. (example: item 1 includes " image + label" and item 2 includes just "label") how can we set size of our cell for this different items. I tried some way but program gives white background instead of image view also with same cell size. Thank you
Mäżcuüd Musse
4 years ago
Cool video brian
HELP & SUPPORT