Nested UICollectionViews
AppStore JSON APIs
To get us started on the Apps page of our application, I'll need to quickly explain how to create a grid of cells using the technique of Nested UICollectionViews. This technique is very simple to implement and all you need are two UICollectionViewController subclasses. To make our job easier, I'll include a few helpers that will speed up the development process in today's lesson. Enjoy.

Comments (17)
antonskwr
4 years ago
Thanks for another great lesson, Brian! Just a little bug I found, we should use minimumInteritemSpacing instead of minimumLineSpacing for a horizontally scrolling grid as written in the documentation, we were just lucky to hit minimumInteritemSpacing default value of 10.0 with our lineSpacing in item height calculation (bigger values will kinda work in our height calculation though, everything less than 10 will break the layout), hope it helps somebody :)
Brian Voong
4 years ago
Tube
4 years ago
The flow layout is not working as I would expect. For 10 items, I expect rows of 4, 4, and 2. Instead, we are getting 4, 3, and 3.
Brian Voong
4 years ago
Tube
4 years ago
I wish I could insert a photo here, but you can see what I mean at the beginning of the App Row Cells video at about 00:27.
Tube
4 years ago
Oh, I see now. We are only looking at 3 cells views of a 10 cell collection. So, all empty cells will be in the last view.
TWei
4 years ago
Hi Brian, thanks for this great series. I have a question, in the cell class, should we use view or contentView property when layout subviews, any differences? I think I read it somewhere, we should use contentView? Thanks
Brian Voong
4 years ago
Dennisvm82
4 years ago
Hi Brian, can you tell me what the difference is between a function that returns a label and the extension with the convenience init? Every time I need a bunch of labels or other views, I just create a function with several parameters, but the convenience init basically does the same thing. It does look a little cleaner, so I might want to start using that instead for my projects. func createLabel(text: String, textColor: UIColor, alignment: NSTextAlignment, lines: Int, size: CGFloat, weight: UIFont.Weight) -> UILabel { let lbl = UILabel() lbl.text = text lbl.textColor = textColor lbl.textAlignment = alignment lbl.numberOfLines = lines lbl.font = .systemFont(ofSize: size, weight: weight) return lbl } extension UILabel { convenience init(text: String, textColor: UIColor, alignment: NSTextAlignment, lines: Int, size: CGFloat, weight: UIFont.Weight) { self.init(frame: .zero) self.text = text self.textColor = textColor self.textAlignment = alignment self.numberOfLines = lines self.font = .systemFont(ofSize: size, weight: weight) } }
mannymarco
4 years ago
Hi Brian. First, thanks for recommending I purchase this course, it's proving invaluable. Will it be relatively straightforward to integrate in to an existing project that uses storyboard? For example, could I have the "AppsPageController" on the storyboard and then work programatically of of that? Thanks Matt
Hwang.the.human
4 years ago
Hello, Brian! What cause of disappearing cells? When I start moving cells, they are disappearing. Is that something with constraints?
Brian Voong
4 years ago
stonypig1
4 years ago
hello: would you explain that how to choose awakefromnib and init(frame: ) when using inside view cell and wut is difference? thanks so much
Brian Voong
4 years ago
Travis Chapman
4 years ago
Hi Brian, I was looking everywhere online for an example of nested collection views with support for dynamic height (allow the content of the collection view cells to shrink and grow dependent on the contents of the cells). I purchased your course, because it was something I came across and I thought the videos about nested collection views would help, but unfortunately it looks like you are hardcoding the height values. Can you provide any further guidance on this? If not, would a refund be applicable? I didn't download anything or watch more than 2 of your videos on nested collection views. Let me know, thanks!
Travis Chapman
4 years ago
You responded to my email, thanks! I'll give that a try
imchristian
4 years ago
Hi Brian, kind of the same situation here, I don't want a refund or something like that but I do want to know if you can share me some resource about dynamic height cells inside nested collection views I REALLY need some examples or tutorials thank you!
Brian Voong
4 years ago
imchristian
4 years ago
Thank you so much for the info Brian!
Chad-michael Muirhead
4 years ago
yo sameeee its so hard to find one online
tesnik
4 years ago
Hey Brian, can you make a course about some of famous iOS architectures (e. g. MVVM, VIPER, MVP, or any clean architecture)? Would be very useful P.S: thanks for that course
Mido Cool
4 years ago
so far so good ^.^
Douglas Moreira
3 years ago
I couldn't understand the math to get the three lines at the end >_<
dclawson
3 years ago
UICollectionView has the task of figuring out how to best place the cells you give it within its view. As we've seen in other videos, if they're small cells compared to the view, it just fits them in and wraps them around until it's full, and then it starts to scroll so you can see all of them. Well, with us, we want to kind of trick the view into making a swiping menu like you see, so we force the width of the cell to be the view's width (not counting the padding for now). If we did that, we could find that if we wanted three cells to appear at a time, then we would want to make sure that they were just tall enough so that the UICollectionView would fit three in there without pushing the third one to the next column. The hard part about the math at the end (just guessing what you're thinking) is that you now have padding so the cells look separate. Brian is doing what in math is called "parameterization" in the sense that he wants to be able to set the functions up so you can just change one or two variables and have the cells size themselves so they'll fit well. We know we want three, and Brian wisely created "topBottomPadding" and "lineSpacing". That means that he needs to make up an equation that will be able to tell the UICollectionView how tall the cells will be so that it all fits perfectly. Now, we have two methods that control the spacing inbetween the cells, one is set to "lineSpacing" and one uses edge insets to pad the top and bottom. It might help to draw a box and make a little box within the box with those insets on some paper. We're left with a smaller box inside. The other method says that there needs to be spaces inbetween the cells, and that "lineSpacing". So, we're left with a height that needs to be divided up so that there are three cells and that min line spacing. So, on line 40: (almost done) we take the total height. We take away the top and bottom padding twice. We know that three cells will have two gaps in between them, so we take away the line spacing twice, as well. That leaves us with a certain amount of height left over, that we then split up three ways at the end. That three way split gets sent to the UICollectionView, and when it puts it all together, it looks just like Brian has it. Hope that helps.
vamshikrishna
3 years ago
Hey Brain great explanation but one small doubt why is it better to take Collectionview instead of Tableview
Brian Voong
3 years ago
fkeebie
3 years ago
I'm now following the course for the second time utilizing Compositional Layout and have just finished Lesson 10 though I experienced a bit of difficulty in making use of Decoration Item in order to set blue background color to the section like the finished screen image of this lesson. Anyway I'd like to go on.
Nikhil Pandey
3 years ago
There is this code class AppsGroupCell: UICollectionViewCell { let titleLabel = UILabel(text: "App Section", font: .boldSystemFont(ofSize: 30)) let horizontalController = AppsHorizontalController() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .lightGray addSubview(titleLabel) titleLabel.anchor(top: topAnchor, leading: leadingAnchor, bottom: nil, trailing: trailingAnchor) addSubview(horizontalController.view) horizontalController.view.backgroundColor = .blue horizontalController.view.anchor(top: titleLabel.bottomAnchor, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } where both the titleLabel and horizontalController are declared outside the init as CollectionView Cellproperties. But if I declare these two inside the init, then the moment I click cell I can't interact with them and the cell become lightGray (the backgroundColor of the AppsGroupCell, why its so? The modified code is as follows class AppsGroupCell: UICollectionViewCell { override init(frame: CGRect) { super.init(frame: frame) let titleLabel = UILabel(text: "App Section", font: .boldSystemFont(ofSize: 30)) let horizontalController = AppsHorizontalController() backgroundColor = .lightGray addSubview(titleLabel) titleLabel.anchor(top: topAnchor, leading: leadingAnchor, bottom: nil, trailing: trailingAnchor) addSubview(horizontalController.view) horizontalController.view.backgroundColor = .blue horizontalController.view.anchor(top: titleLabel.bottomAnchor, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
romer_96p@hotmail.com
3 years ago
Hi Brian, I have two sets of VerticalStacView holding 2 labels each.. the idea is to constrains these four labels: 2 labels to the right and 2 to the left. Which I have successfully done. However when I rotate back to Portrait from Landscape all labels disappear. Which method could I use from your UIView+Layout file to archive the above?
romer_96p@hotmail.com
3 years ago
I tried setting a UIView in between the two verticalViews inside a regular UIStackView.. didn’t work
Brian Voong
3 years ago
romer_96p@hotmail.com
3 years ago
Thank you Brian. That worked
romer_96p@hotmail.com
3 years ago
Thank you Brian. That worked
Nikhil Pandey
3 years ago
Hi Brian, How to handle device rotation in collection view controller inside another collection view cell. In this case after rotating the device, the collection view embedded inside collection view changes size but doesn't revert to the size again on the device rotation.
Lazaro Ambrosio
3 years ago
Im curious Is this possible using storyboards? If so any advice?:)
Brian Voong
3 years ago
HELP & SUPPORT