Hi. Welcome to this WWDC session on Collection Views.
My name is Olivier Gutknecht and I'm an iOS engineer in the UIKit team.
And today we have a great new addition to UIKit.
Sometimes developing application on iOS is about pushing the limits on UI design, and maybe finding new ways to visualize information. And we think Collection View will be an amazing tool for that.
So, what we're going to talk about today?
First, Collection View! Surprise! And we'll see the basics of Collection View.
The view architecture. How you can actually provide that app and interact with it.
And then, we're going to talk about Flow Layout. And Flow Layout is a standard layout we ship on iOS6 for Collection View.
And you will see how you can tune and tweak flow layout for your application's needs.
So, what can Collection View do for you.
Right. Rows and columns, lines of items.
Something that wasn't that easy to do or elegant in UIKit, so we're improving that.
And actually we already use Collection View on iOS 6.
This brand new clocks app on iPad.
This stub view is just a very simple Collection View.
We use also Collection View in Maps in this new info pane in this photo stub.
We use Collection View in some GameKit UI's. And this thing is going to be a great tool for your applications too.
So, let's get started But first, a small comparison. We already have tools to manage collection of data on all platforms.
On OS X we have NSCollectionView. NSCollectionView, UICollectionView - same name, not exactly the same model.
In AppKit on OS X NSCollectionView is about managing a grid of NSViewControllers.
And the model we use for UICollectionView is actually closer to UITableView.
We have the same common principles.
But let me say that Collection View is not a replacement for UITableView.
We have lots of built in behaviors in Table Views.
That's really one of the measure building blocks we use for iOS application on iPad and iPhone.
And we're not changing that.
We have things like headers, footers and we have edit mode.
We have row animations. Many of these don't really make sense in UICollectionView world.
Because Collection View is more abstract and generic than UITableView.
So, why did we build Collection View? We wanted to give you an extremely flexible way to represent data, content in your applications.
And we wanted to do that while keeping our usual patterns we use all of the place in UIKit.
So Collection View is data source based, it's delegate based.
We use cells and if you use Table View before it should be at home with Collection View.
And we wanted to do that and keep high performance in Collection View.
Even with very large data sets in your app.
So, let's check a quick example.
Let's play that my data set is actually my vacation pictures.
Pictures, some albums and I want to have an app for that.
And what my designer gave me is this.
OK How can I built that with Collection View We actually have 3 important concepts in Collection View.
First - cells.
A cell is really a representation for one item in your data set.
So you might have one picture in that library and you want one cell to represent that.
And in that case you're going to use some UIImageView , set the image.
The important thing here is - cells are really data driven.
It's your data model that drive what is in Collection View for the cell's part, it's based on the data source.
The single concept we use in Collection View is actually a new name for an old id.
It's what we call supplementary views.
And what are supplementary views?
It's when you want to us some views,album titles that already metadata about section. Could be an album title, could be album index, could be a block of text, so story of that album The important thing is it is applied to a section. And like cells is data driven And the reason we don't call that headers and footers is that really the same concept that we used before in Table View.
Collection view is not exactly table-based,right?
So if that small thing a footer maybe, but again it is more generic than that.
So, we decided supplementary views to describe these additional things.
The third concept we use in Collection View and that's new is what we call Decoration Views.
And Decoration Views is not like cells and supplementary views.
It's not thing that is going to be data driven.
It's going to be a view side of the world.
So it's more about the layout of the Collection View.
When you want to add some embellishment to some part.
And here is basically two kinds of views. We have this top part.
Shelf element that will repeat three times.
And Decoration Views are really useful to add, for instance, a background scrolling with your content.
Which again was something that wasn't that easy to do before in Table Views.
And with these three elements I can actually implement the design.
So the view architecture in Collection View: cells, supplementary views on the data side.
Decoration View on the visual/layout side.
Then how do you provide content to a Collection View.
Well we have this Objective-C protocol called UICollectionViewDataSource and that is something that one of your class in your application must implement.
And when we are about to display things on screen we have to call that data source.
A few methods so we can know how many sections do we have, how many items in a given section.
And how should we actually configure our cells or headers - supplementary views - more generic.
So let's see how that works.
The first thing is we call from the Collection View one method on your data source in number of sections in a Collection View.
Actualy you don't have to implement that one. If you don't we assume that we have just one section.
How many sections - 2.
Next step: we're going to ask for each section, how many items do you have in your data source for that section.
Well section 0 - 4 items, section 1 - 5 items.
And then when we are ready to display things on screen, we're going to call on your data source and you must implement that one if you want do display something.
CollectionView cellForItem:atIndexPath and then you should actually fetch what you need in your data set.
And configure the cell we're going to give you.
it's important to note that in this case we will only ask you about these cells for what is actually on screen.
We don't want to allocate cells for every single item in your data set.
That would be a quiet bad idea on memory limited device.
We have another trick for performance. Again it's technique we used before.
It's cell and view reuse. What does that mean?
in this case when we scroll Collection View, that might cause a few cells or views to go off screen, right?
And in that case, we don't want to deallocate these cells. We just are going to move these into a reuse queue.
And when the user is about to scroll again, we need new cells, so we are just going to grab what we have in the reuse queue.
Prepare that by asking you with your data source methods and then we can actually scroll up.
So with that we minimize the number of allocations we need to do.
That works quite well for large data sets.
But we actually improved that.
We were using that technique in Table View before.
And we tweaked that. How?
When you setup a Collection View and that's usually in this viewDidLoad method in your UIViewController.
We ask you to register the class you're going to use for a cell for a reuse identifier.
That is the kind of data, the kind of cell you want.
And after that in your data source method we're going to call you with Collection View index path you want to display.
And what we will need to do is to actually call on the Collection View dequeueReusableCellWithReuseIdentifier.
And then you can actually configure that cell by setting the image But what if we don't have any cell available in reuse queue.
Before we have to check for that.
Because you did alert us by registering that class.
So we know the class for that cell.
So even if we don't have a cell available in the reuse queue.
We can instancing that for you.
That code just goes away.
And we like that so much.
We added the same technique to UITableView.
So, let's summarize.
We always instantiate a cell or supplementary view for you.
You just need to register the class for that cell or that supplementary view of kind, header, footer, anything.
You can also set that cell in Interface Builder and just register the nib.
Something we add before in Table Views.
And then in data source just dequeue.
We have two methods: one for cells and one for supplementary views. So quiet nice and easy.
Then, how do we interact with content.
It's time for yet another Objective-C protocol for you.
UICollectionViewDelegate and that delegate will control how cells are actually highlighted when you tap.
Selected and also we have support for these nice menu actions when you long tap a cell.
And that something we actually improved too.
So, just to be clear on the vocabulary. That cell on the left is highlighted. It's when I touch the screen but before touch up, right?
And on touch up what happens is cell might be selected which is a case for these three other cells.
How did we improve that?
First, on each cell we have two properties: selected and highlighted.
And we define a very precise flow for highlighting and selection in Collection View.
How do that work?
First step is when the finger touch the screen.
Here we call on your delegate if you actually implement that method: collectionView:shouldHighlightItemAtIndexPath: And that's new In Table View you can't control selection.
But even if you don't want cell to be selected you would get that highlighting feedback.
Which is not that good from user experience front of view.
So in Collection View we first ask, should we actually highlight the cell.
And if you return NO to that method we don't highlight.
But we completely bypass the selection process.
If you return YES than we switch that highlighted property to YES and we call on your delegate didHighlightItemAtIndexPath.
The next step is on touch up. Should we actually select that cell.
So again if you choose to implement that method collectionView:shouldSelectItemAtIndexPath: and if you return YES - OK we do a bunch of things.
We switch selected to TRUE. We switch back highlighted to FALSE and the same time we call collectionView:didUnhighlightItemAtIndexPath: and collectionView:didSelectItemAtIndexPath: so you can hook whatever you want on the actual end of the selection process.
Whats next - unselect. When you tap again on cell and in that case we call shouldDeselectItemAtIndexPath: returning YES mean that you deny unselect.
So the cell would stay selected.
If you return YES than we call didDeselectItemAtIndexPath.
and we switch back this selected property to FALSE.
So that's very precise flow for selection and highlight in Collection View.
And of course you can also setup on Collection View if you want selection or multiple selection or non selection after all. And we do the right thing.
Then. Bringing actual content on screen.
We have two interesting things here: cells and layout.
first - cells.
There is one thing you need to know: The Collection View is not in the content business.
It's your content. We do not define any style in Collection View.
So you don't have like Table View things like give me that cell with one image, one label, two labels - no styles at all.
And we do actually a bit more than that.
When we call setHighlighted or setSelected on a cell What we actually do is we walk the entire view subtree for that cell.
And if any view here actually implemented setSelected or setHighlighted we going to call that.
What does that mean?
It mean that if in a Collection View Cell you actually use any standard UIKit control, you will get selection and highlight for free.
Because we’re going to call that on UIKit controls.
The next thing we do and you can do that for your custom views of course the next thing we do is we give you two additional properties in cells.
You can configure backgroundView and selectedBackgroundView.
And if you do that we … to switch when we track selection on backgroundView and selectedBackgroundView So its easy to implement these styles.
So we know what the UICollectionViewCell view hierarchy looks like.
We have UICollectionViewCell and we’re going to supply that.
The first subview is backgroundView.
If you did provide one such view to CollectionViewCell.
The next view is selectedBackgroundView if you did prepare that.
And on top of that is a content view that we setup for you.
And you should really add you own content to that content view not to the main CollectionViewCell view Because that would mean that your views would be behind background and selectedBackgroundView Which wouldn't be a good idea.
OK, now thats what we know about UICollectionView.
It is actually a Scroll View subclass It corporates with UICollectionViewDelegate and UICollectionViewDataSource which are in your application.
And it manages a bunch of cells.
We have something else.
UICollectionViewLayout and UICollectionView doesn’t know anything about how to setup cells on screen It corporates with UICollectionViewLayout instance to do that and maybe just a subclass of that Flow Layout we ship in iOS 6.
But you can actually subclass UICollectionViewLayout What does that mean?
It means that you can bring your own layout to the party A layout responsibility is to compute generate layout information for each cell, supplementary views or decoration views that would be in a Collection View.
and these layout attributes is a few things that you might want to set eventually on a cell like position for a cell, actual size for each cell, but you can also set opacity and even the zIndex if you have overlapping cells with zIndex you can control which cell is going to be above the other you can even setup a simple transform on cells you can scale cell relative to others Because UICollectionViewLayout is actually a class, you can subclass that and add other information that going to give your view to your cell class So what does that mean?
Well that’s a layout that UICollectionViewFlowLayout might generate.
Perfectly fine layout: two sections two supplementary views for either like things and a bunch of cells.
But that is a perfectly fine layout.
It is not generated by flow layout but we have two sections two supplementary views bunch of cells and one of your class subclassing UICollectionViewLayout might actually generate.
So now let’s talk about Flow Layout.
Flow Layout is an interesting class.
Something we wanted to ship to give you some basic behavior for Collection View.
And what we can with CollectionView Flow Layout?
We can go from these simple things something you ask us to do before just grids all items of the same size more complex setup with cells having different sizes headers and footers again different sizes and CollectionView Flow Layout make that easy to do.
So what I one to do know to give you a very short demo of Collection View Flow Layout So this is an extremely simple Collection View with Flow Layout.
and here my cell are just a small label with just one letter and that section is just showing these cells and if we have another section like that I want to display Helvetica.
notice that my cells are now with different size and that is built in UICollectionViewFlowLayout.
Another thing we built in is when you actually rotate your device with a Flow Layout We nicely cross-fade cells we need to.
We actually detect if it’s going to look to good look or not If it doesn't - we cross-fade them for free not have any sync to do here Next demo I want to do is a small gallery app. And I think that something you also requested before a reason to extrording so it much better that just Table View in horizontal mode.
Thats a Collection View and here we have a custom header on the side If your items in that section I go to another section with different insets and yet another section and here i just customize the internal item space between my cells and again we support rotation out of the box.
So that was Flow Layout. The demo of Flow Layout.
And Flow Layout is a line-oriented layout, not grids.
You can configure them as grids but you don't have to.
And because that’s really useful in Flow Layout we do include support for headers and footers.
And to talk about the Flow Layout I’d like to introduce you Luk.
You can bring all kinds of arbitrary layouts to Collection View.
But we built in a tremendous layout that we think is really awesome.
That we shipping in iOS 6 that you guys can use to produce some really great UIs already today.
So I’m gonna talk about UICollectionViewFlowLayout which is built in layout which you just saw on screen during demo.
And all of the different bells&whistles we have for you to tweak in that layout to develop interesting things right out of the box.
So to start out let’s define what’s Flow Layout mean Which is a sort of interesting term to some of us Well we think this is really line-oriented layout We said right upfront you'd be able to do grids and absolutely grids are the generic case of line-oriented layout when the items of the same size.
We end up laying them up in something that looks like grid.
But this could be a grouping line of things that are not of like size.
If you have different sizes we will lay them out sort of on the line until we hit end of the screen we lay on another line.
And we start laying things out again. It’s sort of text system in that sense.
And we have support for headers and footers which you've seen.
We have a bunch of ways to customize the Flow Layout.
And this include everything you’ve seen here.
You can change the item size number one.
You can change the spacing between the lines.
And you can change the spacing between the cells.
You can change the scroll direction.
You know we all familiar with horizontal and vertical scroll when we done the Table View.
And one of the biggest request people had was hey I want something like a Table View that can scroll horizontally.
Well we have given you a horizontally Table View but we give you something better.
We have given you something that can scroll horizontally and display content in whatever way make sense.
The little paining demo Olivier had showed you acted similarly to what horizontal Table View should be in the sense that we only had one cell per row there per column. But we accomplished that by using insets around the section which one to the things one of the bells and whistles that we’ll talk about here.
And you can also specify the sizes that you want to use for your headers and footers.
This is all is built in Flow Layout right now.
So the item size for any particular thing can be configured globally based on a property on the actual Flow Layout and you can just say hey, I want to make my item size 100x100 or whatever it is.
But if you want to be more dynamic than that, you can specify these values through the delegate.
And you'll be able to just say ok per item I want to be maybe item number one is 50x60, item number two is 80x100 that sort of thing.
And your dynamic sizing that way.
Additionally you can specify the spacing between the items.
And we’re specifying it in a minimum because what we actually show in screen might not be exactly be the value that you specify.
You see here if we have this particular layout and you've specified the minimum inter item spacing 20 points OK, everything we have here is 20 points between the items but you might get actually something like this.
You specified 20 points as the minimum but due to the width of the actual collection view to layout everything evenly we expand that gap between the items and so we end up actually in 60 points between the items.
But we guarantee that the spacing between the items be at least a minimum that you provided.
We also provide line spacing.
This is different from the inter item spacing If you have say a vertically scrolling grid then spacing between the items is that horizontal space that you saw on the previous slide but the line spacing also provided as a minimum gives us the ability to provide the definition of how much space is between the individual lines and that’s pretty straightforward if all items are all of the same heights in vertically scrolling layout.
But if you have something that looks like this then maybe this is little less obvious right of the box.
What that actually means, well since that’s a minimum what we mean, what we guarantee is the distance from the bottom furthest down item is to the top of the furthest up item on the following line.
That is the least minimum value that you have specified so thats what minimum line spacing.
So spacing something both of these properties can be configured globally.
We have properties directly on the layout you can say my minimum spacing for the line my minimum spacing for the item is tho match and you done.
For a lot of us this is going to be the way to go.
We set it up when we configure the layout and we’re done.
But just like with item sizing we have delegate methods.
So we can specify this dynamically.
Some sections may have different spacing between the items and between the lines than other sections.
You saw this in Olivier's demo before where different sections had different spacings between the items.
So between these three properties that you talked about you may have started to pick up a pattern that we introducing here in Flow Layout that is everything can be configured globally If you want to use that thing for your Flow Layout everywhere and set it up upfront or you can do it on a pre-delegate basis.
This is true basically for all properties in a Flow Layout.
And the thing that makes this convenient for you is the delegate that the Flow Layout uses is actually the delegate of a Collection View.
So the same delegate that gets the itemdidselect and shouldHighlight all this highlight selection calls that same delegate is going to get calls from the flow layout asking for a thing like item sizing and such so to accomplish that the flow layout actually defined an additional protocol that extends uicollectionviewdelegate and we call it uicollectionviewDelegate flowlayout that defines all of the different customizations that you can make in your delegate to dynamically tweak these properties so thats the pattern that flow layout uses for all of itstweaks so let;s talk about scroll directions and we've promised we can scroll horizontally now and thats is simple as setting scroll direction to be vertical or horizontal and what's important to understand that in flow layout lot of our properties the semantics of them depend on the scroll direction that you using so switching from vertical to horizontal is simple as setting a property but then there are some additional considerations on the other properties that you setting and the values that you returning from your delegate this shows looking what a collection view looks like scrolling vertically and we all know the basically it would look like scrolling horizontally this is what were going to see the line breaking is sort of the opposite dimension of what it was on the vertical direction we laid the items out going horizontally when scroll direction was vertical and then broke down on the next line but with horizontal scrolling we laid the items out vertically so the layout of the lines happens on the opposite dimension of the scroll direction and when we break on the following line end of the bounds so the size of the headers and footers and this what I saudis going to definition is also set via a property or by a delegate method but you specifying the width and a height but were only gonna actually use only one dimension and which dimension we use depends on the scroll direction so this is a header that were going to put into a vertically scrolling collection view using uicollectionvuewflowlayout and you specify some height for that collectionview you actually give us the size cause we have the size for header in section but dimension that we care about is height and we gonna take that height and stretch the view up to fit the bounds of the collectionview so that we will always stretch to fit the collectionview but if alternatively you have horizontally scrolling collectionview well take the size value that you provided to us and well actually care about the width in that case and then we will stretch the height of that headerView to fit the collection view bounds that way so the dimension that we care about depends on the dimension that we are scrolling just as we change the dimension on which the layout lines we change the dimension in which we stretch our headers and footers so to summarize what we have done with headers and footers these a defined as supplementary views in the collection view speak the flow layout actually defines two types of supplementary views that are used section header and section footer namely and you notice that we actually capture the term flow layout out of these definitions and thats because if you go write your own layout you may find that your layout works in section headers and section footers as well and you may reuse these supplementary types in your own layout so in order to get them on screen its really just the same dance that you used to doing with cells you register a class or a nib and then in your data source you ll implement the appropriate methods we will ask you for a view for appropriate kind and you can dequeue a view of the type that you've registered and returning to us its really the same thing that you've done with cells so that should be pretty simple code for write let's talk about section insets this is another little tweak that you can do with your content if you imaging having a bunch of content that looks like this we have got a laid out, bunch of stuff in between section insets is the property on content that allows you to specify a box surrounding a content and then the insets top bottom left and right allow you to shrink that box so that bounding box can change your section and footer state put but your content get laid out in a smaller area that what section inset will do for you we use that in olivier demo before in order to ensure that we only had one column for each of the artistic drawings and that got us a nice little line horizontally scrolling line layout so those also can be configured globally or via the delegate very simple pattern that you'll be used to when you walk out of here i want you to think about a flow layout as your new best friend the flow layout is the thing that you wanna go home and play with tonight when you roll out collection view and you wanna see what is capable of what kind of hovers it can bring to your life for creating new beautiful ui its really really powerfull we have a lot of little bells and whistles that you can tweak in here to produce really great user interfaces that maybe would of take a lot of code to write in iOS 5 but in iOS 6 you'll find yourself building them in the evening so we have a lot of new behaviors and let you do that the amount of time that you save just you gonna buy yourself an ice-cream you'll be so happy about it and all of this that we've shown is almost tip of the iceberg we designed collection view so that layout themselves are subclass able this include collectionviewflowlayout by subclassing collectionviewflowlayout you can provide all kinds of little tweaks specific to whatever your imagination come up with so this is gonna be a really fantastic starting point to make applications that are going to blow us all away and even I can't dream of today so with that id like to invite Olivier back in stage to show us a beautiful demo of capabilities of collection view and wrap this whole thing back together for us First a quick recap so what do we know about the collectionview its data driven view, data source based we do selection ahdn highlight tracking built in for you is based on cell, supplementary views, decoration views and collection view really does't know about the layout thats the job of the layout class but we have more we have fine-grained block based updates when you change your data source we have fine and precise flow of a layout and the collection view is going to manage insertion and deletion of items we have some built in hooks for any mission layout and you saw the one with this rotation cross fade with flow layout collection view is actually a scrollview subclass but its quiet well integrated the layout can know you scrolling and compute some final position for a cell for instance and custom layout thats quiet a big deal in a collection view but i don;t want to talk about that let me show . What we want to do now is to give you a little taste of what collection view can do actually Wat do we have here. Its a very simple flow layout every cell have the same size, Ive just added a few section insets to show you that we have different sections I can actually select on that. I can even add small key frame animation Well when we insert its quiet easy: we just move new cell on the right base and when we remove, if we remove within a section, what do we do actually we just animate sont have anything to do, you get it for free.
for a given collection view with configured with a layout you can call a method on a collection view which is setcollectionviewlaout so you can switch to new layout what do we do in that case well we animate and that is one line of code and note that we keep selection but that grid layout that stacked layout they all rather generic layout, right?
could applied to be cd albums anything one thing you can do, if you right your own layout could be actually pick into your data set and build your layout based on some information about the actual item you want to display like for instance for pictures, i don't know.
GPS coordinates and that just custom layout with one small decoration view one big decoration view and we just animate and when we switch layout like that we actually call method on each cell and are going to appear in the next layout you might start with a cell with a small size and get into layout where cell size is huge you could add additional information like the label from the picture, the date, anything else.
Or what you could do too is just to tweak the visual appearance from that cell so each match is best in a new layout here I'm just changing the corner radius when switching to new layout so thats another custom layout, quiet a simple one and when i implemented that layout i needed two properties one is that reference point for that purser of cells and the other one is the cell distance what thing i could do is to actually add the gesture recognizer on my collection view and just change the distance and that reference point in my layout is just a parameter right?
just call the setter, though pinch and move and Im just changing two things set distance, setpoing and what happens is layout invalidates collection view computes the new state for the cell again it is a few lines of code But what if i just call set distance, set reference point what is going to happen?
in that case we change the parameter of that ltyout so that layout ois going to jump to the next state which visually is not what i want so what we can do is use this fine-grained blockbased update mechanism so we can ask collection view to actually animate when changing parameter in code for layout you can do some really crasy layout please told to your designer before things like circle layout, wave layout that what is actually quiet interesting remembering my first layout the grid one I was adding and removing items from my data set and cell would just appear and disappear or even animate what happen in that vase we tried to do the right thing, which is were going to actually add the cell at the right position or just fade out the cell when we remove the item so everything should just work right of the box but one thing you can do when you implement custom layout you can define the initial position for a cell when its appearing you can define the final state for a cell when its disappearing and what is that initial and final states its that uicollectionviewlayout previews that define cell position cell size cell opacity a simple transform and you can do things like that and that was adding a cell but you can get creativity for deletion that was quiet a simple layout because that transform actually its a catransform3d so what could you do with that something like that and this is actually interesting layout too because when i swipe i actually need to compute again the cell state and collection view just striking that and asking layout at the right time you might notice that i just scroll that the cell perfectly starts in place and that was a scrollview slash layout integration that i was talking about and of course selection still work so my last layout is my final layout that was not a keynote animation that was a ten lines layout one thing about this demo.