WWDC2012 Session 205

Transcript

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.
Not anymore!
Why?
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.
Stops here.
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.
Every single layout is about one page of code its that easy to create new custom layout with collectionview
so collection view is all about your content
cells layouts
simple things quiet simple because we ship flow layout for you
and we can't wait to see what you going to do with that
so for more information please check uikit api documentation
male Jake Behrens evangelist
and we have these iOS 6 developer forums online